Я не уверен, как точно выразить, в чем заключается моя проблема, поэтому я просто углублюсь в то, что сделал, и опишу проблему по мере ее возникновения. Актуальный вопрос в конце поста.
Я использую EF 4.3 с первым кодом, и у меня есть общая сущность Category для организации различных типов контента:
public enum ContentType { Articles, Videos };
public class Category
{
public long ID { get; set; }
public long? ParentCategoryID { get; set; }
internal int ContentTypeValue { get; set; }
public string Title { get; set; }
public virtual Category ParentCategory { get; set; }
public virtual ICollection<Category> ChildCategories { get; set; }
public ContentType ContentType
{
get { return (ContentType) ContentTypeValue; }
set { ContentTypeValue = (int) value; }
}
}
Это сопоставлено с базой данных, используя следующие определения (я использую вспомогательный класс, но Map просто ссылается на конкретный построитель модели для сущности):
Map.Property( e => e.ContentTypeValue ).IsRequired().HasColumnName( "ContentType" );
Map.Property( e => e.Title ).IsRequired().HasMaxLength( 200 );
Map.HasOptional( e => e.ParentCategory ).WithMany( r => r.ChildCategories ).HasForeignKey( e => e.ParentCategoryID ).WillCascadeOnDelete( false );
Обратите внимание, что Category не предоставляет ссылки на другие типы объектов (кроме самого себя).
Затем я добавил сущность Article и отображение для нее:
public class Article
{
public long ID { get; set; }
public long CategoryID { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public virtual Category Category { get; set; }
}
Map.Property( e => e.Title ).IsRequired().HasMaxLength( 50 );
Map.Property( e => e.Body ).IsRequired().HasMaxLength( 4000 );
Map.HasRequired( e => e.Category ).WithMany().HasForeignKey( e => e.CategoryID ).WillCascadeOnDelete( false );
Это работает нормально и создает таблицу Article с PK (ID) и FK (CategoryID) для таблицы Category.
Следующим шагом было добавление аналогичного определения сущности и отображения для Видео, которое также работало как ожидалось.
public class Video
{
public long ID { get; set; }
public long CategoryID { get; set; }
public string Title { get; set; }
public string FileName { get; set; }
public virtual Category Category { get; set; }
}
Map.Property( e => e.Title ).IsRequired().HasMaxLength( 50 );
Map.Property( e => e.FileName ).IsRequired().HasMaxLength( 200 );
Map.HasRequired( e => e.Category ).WithMany().HasForeignKey( e => e.CategoryID ).WillCascadeOnDelete( false );
Однако теперь я хотел бы, чтобы Article имела прямую ссылку на конкретное видео (независимо от того, к какой категории относится любая из них), поэтому, по сути, ссылка 1: 1 (обязательный: необязательный) между ними.
public class Article // broken
{
public long ID { get; set; }
public long CategoryID { get; set; }
public long? VideoID { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public virtual Category Category { get; set; }
public virtual Video Video { get; set; }
}
А для отображения класса я использовал бы следующее:
Map.Property( e => e.Title ).IsRequired().HasMaxLength( 50 );
Map.Property( e => e.Body ).IsRequired().HasMaxLength( 4000 );
Map.HasRequired( e => e.Category ).WithMany().HasForeignKey( e => e.CategoryID ).WillCascadeOnDelete( false );
Map.HasOptional( e => e.Video ).WithMany().HasForeignKey( e => e.VideoID ).WillCascadeOnDelete( false );
Как только я добавлю такую ссылку, EF не сможет создать схему базы данных с DbUpdateException, сообщение об ошибке которого будет иметь вид "Невозможно определить основной конец (имя ограничения). У нескольких добавленных объектов могут быть одинаковые первичный ключ. "
Я могу решить эту проблему, не имея ссылку на видео категории (или не имея ссылки на статью видео, как показано в первом показанном коде), но это противоречит общей цели класса категории и вынудит меня поддерживать ArticleCategories, VideoCategories. и т. д.
Чтобы было совершенно ясно, что мне нужно, вот схема, которую я хотел бы закончить (обратите внимание: CategoryID в видео не должен быть обнуляемым, в отличие от изображения):
![Database diagram](https://i.stack.imgur.com/9jFMZ.jpg)
Как определить такое отношение, используя беглую нотацию в коде?