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?
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.
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