Reputation: 1548
I'm pretty new to entity framework and not an expert on database architecture, so I'm struggling to know what terms to Google for the question I have.
Say I have various entities, like Joke, Image, Story, Cartoon. They all have different data, but they share the fact that they all have an Id. In my case, a Guid.
I want to have an entity called Comment which just stores the comment, the user who made the comment, and the Id of the item commented on - which can be any of the types above. I don't want to have to create a JokeComments table, ImageComments, StoryComments etc. - because that seems inefficient - having to maintain many classes for every 'commentable' item, and means that I can't easily just grab all comments from a single User.
So I have something like this
public abstract class IdentifiableObject
{
public IdentifiableObject()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
}
public class Joke: IdentifiableObject
{
public List<Comment> Comments {get; set;}
}
public class Story : IdentifiableObject
{
public List<Comment> Comments {get; set;}
}
public class Comment
{
public Guid Id {get; set;}
public String Comment {get; set;}
[Key, ForeignKey ("IdentifiableObject")]
public Guid TargetId {get; set;}
}
But this doesn't work, and I have no idea where to start Googling. I've read about using Interfaces, but I couldn't work out how that would work in this situation. Do I need to add a 'TargetType' property in the Comment class? If so, what would the type be? If I leave out any key in the Comment class, it creates a FK for every type it can be associaated with, which leaves me with the problem of knowing how to retrieve the target.
Can anyone explain to me how I would approach this requirement in EntityFramework, or just let me know what the name of what I am trying to do is, to help point me in the right direction on Google? Thanks..
Upvotes: 1
Views: 668
Reputation: 21490
It's not a great or direct answer to your question, but you can create a base class with the comments property, and it'll work;
public abstract class CommentedObject
{
public List<Comment> Comments {get; set;}
public class Joke: CommentedObject
{
}
public class Story : CommentedObject
{
}
public class Comment
{
public Guid Id {get; set;}
public String Comment {get; set;}
[Key, ForeignKey ("IdentifiableObject")]
public Guid TargetId {get; set;}
}
It's nasty, in that it involves inheritance to solve the problem, but it works.
You might want to read about the EF table per hierarchy and table per type strategies.
Upvotes: 1