EF будет следовать некоторым соглашениям по умолчанию для разработки отношений FK.Ошибка, которую вы видите, связана с тем, что Author имеет коллекцию Titles, а EF пытается автоматически установить 1-ко-многим между двумя.Он ожидает найти «Author_ID» в Заголовке, который не существует, потому что ваша схема настроена с помощью объединяющей таблицы с именем TitleAuthor.
Чтобы решить эту проблему, вам необходимо сопоставить сущность TitleAuthor, вкоторый Author будет содержать коллекцию TitleAuthors, которые ссылаются на сущность Author и Title.EF может автоматически отображать объединяющиеся таблицы, если эти таблицы состоят только из двух FK.Как только вы захотите ввести дополнительные поля, вам нужно определить присоединяющуюся сущность.
public class TitleAuthor
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; internal set;}
public virtual Title Title { get; internal set;}
public virtual Author Author { get; internal set;}
// add other properties as needed..
}
Итак, от вашей сущности Author:
public virtual ICollection<TitleAuthor> Authors {get; internal set;} = new List<TitleAuthor>();
Чтобы получить доступ к заголовкам для автора:
author.Titles.Select(x => x.Title);
Я бы порекомендовал прочесть о сопоставлении многие ко многим с EF.Я всегда использую преднамеренное отображение с EF, а не полагаюсь на его соглашения.Это просто помогает сделать его более предсказуемым.
Если вы используете значения по умолчанию для PK, вам нужно сообщить EF через атрибут DatabaseGenerated
.Это не требуется для операций чтения, но будет необходимо при вставке записей.
Кроме того, для SQL Server рассмотрите возможность использования NewSequentialId()
в качестве значения по умолчанию для ваших UUID PK.Они более дружественны к индексам, чем NewId()
.
. Приведенный выше пример использования внутренних сеттеров (тоже для частных работ) для поощрения использования сущностей в стиле DDD.Публичные сеттеры могут привести к злоупотреблению / злоупотреблению сущностями в том смысле, что контекст будет старательно пытаться сохранить все, что вы установили.Как правило, рекомендуется ограничить функциональность, которая будет изменять состояние объекта, методом в объекте с необходимыми аргументами для проверки или хранилищем.Я использую внутреннюю область видимости, чтобы позволить модульным тестам по-прежнему инициализировать объекты.(используя InternalsVisibleTo
между доменом и сборочными единицами)