Entity Framework 4.1 InverseProperty Attribute

I add an example for the InversePropertyAttribute. It cannot only be used for relationships in self referencing entities (as in the example linked in Ladislav’s answer) but also in the “normal” case of relationships between different entities:

public class Book
{
    public int ID {get; set;}
    public string Title {get; set;}

    [InverseProperty("Books")]
    public Author Author {get; set;}
}

public class Author
{
    public int ID {get; set;}
    public string Name {get; set;}

    [InverseProperty("Author")]
    public virtual ICollection<Book> Books {get; set;}
}

This would describe the same relationship as this Fluent Code:

modelBuilder.Entity<Book>()
            .HasOptional(b => b.Author)
            .WithMany(a => a.Books);

… or …

modelBuilder.Entity<Author>()
            .HasMany(a => a.Books)
            .WithOptional(b => b.Author);

Now, adding the InverseProperty attribute in the example above is redundant: The mapping conventions would create the same single relationship anyway.

But consider this example (of a book library which only contains books written together by two authors):

public class Book
{
    public int ID {get; set;}
    public string Title {get; set;}

    public Author FirstAuthor {get; set;}
    public Author SecondAuthor {get; set;}
}

public class Author
{
    public int ID {get; set;}
    public string Name {get; set;}

    public virtual ICollection<Book> BooksAsFirstAuthor {get; set;}
    public virtual ICollection<Book> BooksAsSecondAuthor {get; set;}
}

The mapping conventions would not detect which ends of these relationships belong together and actually create four relationships (with four foreign keys in the Books table). In this situation using the InverseProperty would help to define the correct relationships we want in our model:

public class Book
{
    public int ID {get; set;}
    public string Title {get; set;}

    [InverseProperty("BooksAsFirstAuthor")]
    public Author FirstAuthor {get; set;}
    [InverseProperty("BooksAsSecondAuthor")]
    public Author SecondAuthor {get; set;}
}

public class Author
{
    public int ID {get; set;}
    public string Name {get; set;}

    [InverseProperty("FirstAuthor")]
    public virtual ICollection<Book> BooksAsFirstAuthor {get; set;}
    [InverseProperty("SecondAuthor")]
    public virtual ICollection<Book> BooksAsSecondAuthor {get; set;}
}

Here we would only get two relationships. (Note: The InverseProperty attribute is only necessary on one end of the relationship, we can omit the attribute on the other end.)

Leave a Comment