How to determine the EF-code first three-phase relationship FK? (parent with two siblings)

I'm not sure how to accurately express my problem, so I’ll just dive into what I did and describe the problem as it arises. The actual question is at the end of the post.

I use EF 4.3 with code one and have this common category object for organizing various types of content:

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; } } } 

This maps to the database using the following definitions (I use a helper class, but Map just refers to the specific model builder for the object):

 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 ); 

Please note that the Category does not provide references to other types of entities (except itself).

Then I added an Article object and its display:

 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 ); 

This works fine and creates an article table with PK (ID) and FK (CategoryID) in the Category table.

The next step was to add a similar object and define a display for the video, which also worked as expected.

 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 ); 

However, now I would like for the article to have a direct link to a specific video (regardless of which category one of them is in), therefore essentially a 1: 1 link (required: optional) between the two.

 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; } } 

And to map the class, I would use the following:

 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 ); 

As soon as I add such a link, EF cannot create a database schema using DbUpdateException, whose error message matches the lines "Unable to determine the main end (constraint name). Several objects added may have the same primary key.

I can solve this problem without video ads (or without a link to an article link, as in the first code shown), but this will defeat the general purpose of the Category class and force me to support ArticleCategories, VideoCategories, etc.

To be completely clear what I need, here is the diagram I want to end with (note: CategoryID in the video should not be null, contrary to the image):

Database diagram

How to determine this relationship using a freely written code label?

+4
source share
2 answers

I can not reproduce the problem, your configs are fine (I use automatic migrations here).

Can you add the exact error he gave you?

Anyway, my exact code is: https://gist.github.com/1961958

And what is the generated SQL from the update database: https://gist.github.com/1961961

EDIT: ops, I have not seen the exact same answer from @BalazsTihanyi, sorry.

+1
source

Strange, but it all works for me. I cannot reproduce the error from your submitted code.
What if you are trying to recreate your tables from migration 0?

+1
source

Source: https://habr.com/ru/post/1398685/


All Articles