I am trying to implement a model in EF6 using inheritance
I have a the following classes:
Base
Comments
Page : Base
BlogPost : Base
Where both Page and BlogPost use comments in the same manner. So I define Base as
public class Base
{
public int ID { get; set; }
// ...
public ICollection<Comment> Comments { get; set; }
}
And the comments class defined like so:
public class Comment
{
public int ID { get; set; }
public int RelatedItemID { get; set; } // points to Base::ID
public string Text { get; set; }
}
Suppose I want to set up the database as "Table per Type", so there are individual tables for Page and BlogPost each with auto-increment int PK.
Now the EF know which table Comment.RelatedItemID points to? i.e. Page or BlogPost
What is the best way to implements this without having to resort to "Table Per Hierarchy"?
I want to set up the database as "Table per Type", so there are individual tables for Page and BlogPost each with auto-increment int PK
Here's a problem.
The description looks like TPC, but since you want to use auto-increment primary keys for each descendant, it won't fit TPC, because ultimately you'll get duplicating primary keys in one entity set. Obviously, it isn't TPT too, because TPT assumes, that there is a "base" table with auto-increment IDs, while "derived" tables have non-auto-increment primary keys, that at the same time are foreign keys to "base" table.
It seems to me, that logically these entities are not related. I mean, that there are no cases, when you will want to query pages and blog posts, using single query. Hence, it is better to avoid inheritance in EF model.
I suggest you to re-design model this way:
// "abstract" tells EF, that this type doesn't require mapping
public abstract class CommentBase
{
public int ID { get; set; }
public int RelatedItemID { get; set; }
public string Text { get; set; }
}
public class PageComment: CommentBase {}
public class BlogPostComment : CommentBase {}
public abstract Base<TComment>
where TComment : Comment
{
public int ID { get; set; }
// ...
public ICollection<TComment> Comments { get; set; }
}
public class Page : Base<PageComment> { /* other page properties */ }
public class BlogPost : Base<BlogPostComment> { /* other blog post properties */ }
There is still inheritance in code, but there will be two different entity sets in EF model. OTOH, you'll get two separate tables with comments - one for pages, one for blog posts.