One-to-one relationship in CF Entity Framework using mapping

℡╲_俬逩灬. 提交于 2019-12-07 14:42:10

问题


I'm using Entity Framework 5, Code-First.

I've two domain objects (or tables). 1st is User, and 2nd is UserProfile. One user can have only one profile, and one profile belongs to only one user. That is 1-1 relationship.

Here are the classes.... (I simplified the code to make it understandably, It is actually more complex)

User

public class User {
    public virtual Int64 UserId { get; set; }
    public virtual UserProfile UserProfile { get; set; }
    public virtual String Username{ get; set; }
    public virtual String Email { get; set; }
    public virtual String Password { get; set; }
}

UserProfile

public class UserProfile {
    public virtual Int64 UserId { get; set; }
    public virtual User User { get; set; }
    public virtual Int64 Reputation { get; set; }
    public virtual String WebsiteUrl { get; set; }
}

Here are the Maps....

UserMap

public UserMap() {
    this.Property(t => t.Email)
        .IsRequired()
        .HasMaxLength(100);
    this.Property(t => t.Password)
        .IsRequired()
        .HasMaxLength(15);
    this.Property(t => t.Username)
        .IsRequired()
        .HasMaxLength(15);
}

UserProfileMap

public UserProfileMap()
    {
        this.HasKey(t => t.UserId);
    }

Here is the Context....

public class TcContext : DbContext {
    static TcContext () {
        Database.SetInitializer(new TcContextInitializer());
    }
    public DbSet<User> Users { get; set; }
    public DbSet<UserProfile> UserProfiles { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Configurations.Add(new UserMap());
        modelBuilder.Configurations.Add(new UserProfileMap());
    }
}

And here is my error message....

Unable to determine the principal end of an association between the types 'Tc.Domain.UserProfile' and 'Tc.Domain.User'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

I think in this way EF should determine the relationship automatically. But it gives me the above error message. I've researched this problem for a while but can't find a good illustration of the problem in my case.

Where is my mistake? Or, should I define some sort of additional relations in maps?


回答1:


I had to modify the UserMap class as follows

public UserMap() {
    this.Property(t => t.Email)
        .IsRequired()
        .HasMaxLength(100);
    this.Property(t => t.Password)
        .IsRequired()
        .HasMaxLength(15);
    this.Property(t => t.Username)
        .IsRequired()
        .HasMaxLength(15);
    this.HasOptional(t => t.UserProfile)
        .WithRequired(t => t.User);
}

It essentially says: "User has an optional entity UserProfile which in turn has a required User entity"

The definition of the key in UserProfile is a must here.




回答2:


Just looked at it again, do you need to add HasKey to UserMap so it knows which one is the key otherwise you could do the following :-

Are you able to change UserProfile to inherit from User and then add this to your OnModelCreating method

modelBuilder.Entity().ToTable("UserProfile");

this will create your one to one relationship on the database. I had to do this with my current model to get one to one otherwise if you do not specify the ToTable part it will lump them into one table with a Discriminator column

cheers Mark



来源:https://stackoverflow.com/questions/16998863/one-to-one-relationship-in-cf-entity-framework-using-mapping

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!