Ответ 1
Я добавляю пример для 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;}
}
Соглашения о сопоставлении не будут определять, какие концы этих отношений принадлежат друг другу, и фактически создать четыре отношения (с четырьмя внешними ключами в таблице "Книги" ). В этой ситуации использование 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
необходим только на одном конце отношения, мы можем опустить атрибут на другом конце.)