Я добавляю пример для InversePropertyAttribute
.Он не может использоваться только для отношений в сущностях, на которые есть ссылки (как в примере, связанном с ответом Ладислава), но также и в «нормальном» случае отношений между различными объектами:
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;}
}
Это будет описывать одни и те же отношениякак этот свободный код:
modelBuilder.Entity<Book>()
.HasOptional(b => b.Author)
.WithMany(a => a.Books);
... или ...
modelBuilder.Entity<Author>()
.HasMany(a => a.Books)
.WithOptional(b => b.Author);
Теперь добавление атрибута InverseProperty
в приведенном выше примере является излишним: соглашения об отображении создадутто же самое одиночные отношения в любом случае.
Но рассмотрим этот пример (из библиотеки книг, которая содержит только книги, написанные вместе двумя авторами):
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;}
}
Соглашения по отображениюне обнаружит, какие концы этих отношений принадлежат друг другу, и фактически создаст четыре отношения (с четырьмя внешними ключами в таблице Books).В этой ситуации использование InverseProperty
поможет определить правильные отношения, которые мы хотим в нашей модели:
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;}
}
Здесь мы получим только два отношения .(Примечание: атрибут InverseProperty
необходим только на одном конце отношения, мы можем опустить атрибут на другом конце.)