Entity with multiple members of the same type in the Entity Framework

Asked

Viewed 549 times

5

When we have two entities related to Many-to-Many and create the navigation properties correctly Entity creates an extra table to configure that relationship.

In the case I’m working I have a structure that in the best of worlds would look like this:

public class User {
    public string Name {get;set}
    public int id
}

public class Forum {
    public string Title {get;set}
    public virtual ICollection<User> Participants {get;set}
    public virtual ICollection<User> Followers {get;set}
}

The problem here is precisely because it has two properties of the User type. Entity will try to store everything in the same table, and will create two foreign keys in User.

What is good practice in this case? It would create two different entities (Participants and Followers) and save User and Forum ids in each of them?

  • First of all, beware of restricted words, "User" for example usually gives error because it is used internally by EF if I am not mistaken. Try to be the most specific, use your system. In your case, both 'Participants' and 'Followers' are 'User', so I ask, how to know who is who? In my view you have two options, create specializations so that 'Participant' and 'Followers' inherit 'User'. Or create a new property in 'User' to save the type of user, an Enum of type 'Usertype' already serveria, where you point out if it is 'Participant' or 'Follower'.

  • @Stefanosandes , is using code first?

  • Yes @Vinicius, code first.

  • 1

    @petersonfortes understood your idea. The question is, when it comes to object orientation, two collections of the same type are easily distinguished, but in BD, how do you adjust Entity to map this to two tables? I can create two specialized classes as you said yes, but it seems to me that I would be thinking in a recurtional way, not OO. As for typing, it would make no sense in a large application where references can be in many entities. Thank you very much!

  • @Stefano Sandes as far as I understand object orientation in a database is myth, the idea is very old, but in practice it doesn’t exist. Unfortunately the Entity Framework can not magically solve this kind of thing for you, the solution is to change your EDMX in hand, even so this is a mess because whenever there is a change in the bank and you have to update your EDMX, you will have to redo these manual changes. Using some logic in your business layer in my opinion is the best solution, for this case.

  • I understood @petersonfortes. I was hoping there was a way to set you up for this. I have worked with database-first and managed to make Nhibernate understand this type of relationship. Thank you very much!

  • @Stefano Sandes I’m currently working with Nhibernate too and it’s beautiful. I don’t miss EF at all.

Show 2 more comments

1 answer

3

What is good practice in this case?

It depends on what you need. If you need the data to be unified, the approach is correct. If this is not necessary, it is pertinent to separate.

In case of unified structure, upgrade to the following:

public class User 
{
    public int id
    public int? ForumParticipantId { get; set; }
    public int? ForumFollowerId { get; set; }
    public string Name { get; set; }

    public virtual Forum ForumParticipant { get; set; }
    public virtual Forum ForumFollower { get; set; }
}

public class Forum 
{
    public int id { get; set; }
    public string Title { get; set; }

    [InverseProperty("ForumParticipant")]
    public virtual ICollection<User> Participants { get; set; }
    [InverseProperty("ForumFollower")]
    public virtual ICollection<User> Followers { get; set; }
}

See more about the [InverseProperty] here.

  • I get it. What bothers me a little in this approach is the fact that entities become inflated of properties that in the end end end end up serving only to teach Entity what to do. In a medium-sized application, imagine how many User entities you can refer to.. In the end, the User class would end up with several properties. That’s what I meant by "good practice". Is this really the best case scenario? Maybe in a case like this it would be better to open from the navigation prop. Thank you very much Gypsy!

  • Let’s just put ourselves in the shoes of the framework developer: have you ever thought about how hard it is to put all this intelligence into it? Despite the decor, everything works.

  • I agree that there should be a great level of difficulty, but I disagree about putting myself in the place of "the developer". If I go from that assumption, nothing does anything that’s too difficult. Anyway, it is not a requirement on what the framework should have or not, on the contrary, it is a question about what would be good practice for cases like this. Anyway, thank you so much for your help.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.