entity-frameworkcode-firstmodelingentity-model

How do I map two relationships between the same two entities?


Some advice on how to even properly describe these relationships would be a great start. Something accurately described is a problem looking for a solution. I have entities User and Login, where Login describes basically a login session for one user. So, User normally has many Login instances. This relationship is only described on the Login side with a required, single User navigation property, and there is an implied, but not declared, Login collection on the User side.

Then, for the other relationship, a User is created under authorization of a Login, so this relationship is described on the User side, with a Login navigation property, and there is an implied, but not User collection on the Login side.

I don't do much DB modelling outside of using the DB tools, and they always just get relationships right for me, but now, I have to map these relationships for code first, using fluent mapping. How do I described these two relationships, what are the principle and dependent sides, and what are the multiplicities here?


Solution

  • Code First tries to link up the two sides of what are probably the same relationship. When you instead have two different unidirectional relationships, then you need to tell Code First this by explicitly telling Code First that the inverse navigation property does not exist using WithMany() with no arguments:

    public class User
    {
        public int Id { get; set; }
        public int LoginId { get; set; }
        public virtual Login Login { get; set; }
    }
    
    public class Login
    {
        public int Id { get; set; }
        public int UserId { get; set; }
        public virtual User User { get; set; }
    }
    
    public class SomeContext : DbContext
    {
        public DbSet<User> Users { get; set; }
        public DbSet<Login> Logins{ get; set; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<User>()
                .HasRequired(e => e.Login)
                .WithMany()
                .HasForeignKey(e => e.LoginId);
    
            modelBuilder.Entity<Login>()
                .HasRequired(e => e.User)
                .WithMany()
                .HasForeignKey(e => e.UserId);
        }
    }