Toby
Toby

Reputation: 1548

Entity Framework - Allow multiple classes to have a list of items with the same class type

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

Answers (1)

Steve Cooper
Steve Cooper

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

Related Questions