-1

I have this one-to-many relationship, Profile -> Follower and I need a way to say the Follower is some Profile (user). How do I create the structure so that I designate the Follower as a specific Profile? I guess I could just stick in an id of the profile but I'd like to have a key back to the profile entity

Here is 'profile' and 'follower' entities

suedo code here

public class Profile {
  public virtual ICollection<Follower> Followers { get; set; }    // one to many
}

public class Follower {
    [Key]
    public int FollowerId { get; set; }

    public int ProfileRefId { get; set; }

    // one-to-many here
    [ForeignKey("ProfileRefId")]
    public virtual Profile Profile { get; set; }

    public DateTime Created { get; set; }


    // code that shows the follower is some specific profile/user
    ????

}
chuckd
  • 13,460
  • 29
  • 152
  • 331

1 Answers1

0

You mentioned that you have a one-to-many relation between a Profile and a Follower.

Normally this means that every Profile has zero or more Followers, and every Follower belongs to one Profile. In other words: a Follower HAS a Profile, not IS a Profile. In software design terms: a Follower uses Composition to describe its relation with a Profile. It does not use inheritance.

The reason for this, is because if you have one Profile P1 that has two Followers F1 and F2, both Followers have something that refers to the same P1.

The effect is that when changing any of the properties of the Profile of follower F1, these properties are also changed in the Profile of follower F2. This is expected behaviour, because the Profile of F1 is the same Profile as the Profile of F2.

If you would use inheritance to model the Profile part of the Followers, than F1 and F2 both would have their own Profile. Changing the Profile properties of F1 would not change the Profile Properties of F2.

If you really want the latter, your design is not a one-to-many relation. See later how to implement inheritance

Proper configuration of one-to-many relation:

class Profile
{
    public int Id {get; set;}

    // a Profile has zero or more followers:
    public virtual ICollection<Follower> Followers {get; set;}
    ...
}

class Follower
{
    public int Id {get; set;}

    // a follower belongs to exactly one Profile (via foreign key ProfileId)
    public int ProfileId {get; set;}
    public virtual Profile Profile {get; set;}
    ...
}

The advantage is that entity framework automatically recognizes this as a one-to-many relation. No attributes, nor fluent API needed. Besides: fellow developers will immediately see that you meant to design a one-to-many relation.

Inheritance in entity framework

If you intended to implement inheritance, there are several strategies to do this. The one I use most often is Table-Per-Concrete-Class (TPC).

In TPC every class that will have instantiated objects gets its own table. This table has the properties of the class plus the properties of the base classes.

This design is the easiest to understand by others, and gives the most simple database with fast retrieval and update. For every object that you want to access only one table is needed.

Besides this mimics exactly software behaviour of inheritance: if you create a Follower object, this object automatically has the Profile properties. If you delete the Follower object, its Profile properties are also deleted. Changing one of the Profile properties of the Follower, does not influence the Profile properties of any of the other Followers.

class Profile
{
     ... // profile properties
}

// A Follower IS a Profile:
class Follower : Profile
{
    public int Id {get; set;}
    ... // Follower properties
}

class MyDbContrext : DbContext
{
    public DbSet<Follower> Followers{get; set;}

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // tell that the Profile base class properties of Follower should be in the
        // Followers table:
        modelBuilder.Entity<Follower>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable(nameof(MyDbContext.Followers));
        });
    }
Harald Coppoolse
  • 28,834
  • 7
  • 67
  • 116
  • I made the appropriate changes to create the correct one-to-many relationship. But my underlying question really relates to creating the 'Follower' table with two foreign keys back to the same table 'Profile'. Where one will be the parent and the other key will be back to some random profile (the follower). I found what I was looking for here https://stackoverflow.com/questions/28570916/defining-multiple-foreign-key-for-the-same-table-in-entity-framework-code-first – chuckd Aug 10 '17 at 05:42
  • It is better to edit your question so that it really expresses the basis of your problem. "My underlying question", why have secret underlying question? Why not just write them in your question instead. Why say you have one to-many, while in fact your question is that you have a class with two references to another table? If you ask questions please try to help the answerers by writing the proper requirements instead of letting them guess. – Harald Coppoolse Aug 10 '17 at 06:35