Entity Framework codefirst issueUnable to determine the principal end of an association between the types

StackOverflow https://stackoverflow.com/questions/21976541

Domanda

So I'm trying to use the MVC 4 internet application template and the UserProfile database tables it creates for accounts and then add tables that have dependencies on the UserProfile table for additional information.

The model would be UserProfile 0 ---> 1 UserType1 and UserProfile 0 ----> UserType2 where the userprofile table may have a dependent record in UserType1 and may have a dependent record in UserType2 and if there is an entry in either UserType1 or UserType2 its primary key is a foreign key that is the UserId from User Profiles

The POCO is:

public class UserProfile
{

    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string Email { get; set; }
    public string UserName { get; set; }
    public int type { get; set; }
    public virtual UserType1 UserType1 { get; set; }
    public virtual UserType2 UserType2 { get; set; }

public class UserType1
{ 
  [key,ForeignKey("UserProfile")]
  public virtual int UserId {get;set;}
  public int myval {get;set;}
  public UserProfile UserProfile {get; set;}
}

public class UserType2 //same as usertype 1 

I've tried adding model mapping statements but to no avail

Model mapping data for user profile:

public class UserProfileMap : EntityTypeConfiguration<UserProfile>
{
    public UserProfileMap()
    {
        // Primary Key
        this.HasKey(t => t.UserId);

        // Properties
        this.Property(t => t.Email)
            .IsRequired()
            .HasMaxLength(56);

        this.Property(t => t.UserName)
            .IsRequired()
            .HasMaxLength(50);

        // Table & Column Mappings
        this.ToTable("UserProfile");
        this.Property(t => t.UserId).HasColumnName("UserId");
        this.Property(t => t.Email).HasColumnName("Email");
        this.Property(t => t.UserName).HasColumnName("UserName");
        this.Property(t => t.UserType).HasColumnName("UserType");

        this.HasOptional(e => e.UserType1).WithRequired();

The model mapping data for usertypes looks like this:

public class UserType1 : EntityTypeConfiguration<UserType1>
{
    public UserType1Map()
    {
        // Primary Key
        this.HasKey(t => t.UserId);

        // Properties
        this.Property(t => t.UserId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

        this.HasRequired(t => t.UserProfile).WithOptional();


        this.Property(t => t.Company)
            .IsRequired()
            .HasMaxLength(50);

        // Table & Column Mappings
        this.ToTable("UserType1");
        this.Property(t => t.UserId).HasColumnName("UserId");
        this.Property(t => t.Company).HasColumnName("Company");


        // Relationships
        this.HasRequired(t => t.UserProfile).WithOptional();

    }
}

But I always get this error Unable to determine the principal end of an association between the types 'myApp.Models.UserType1' and 'myApp.Models.UserProfile'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

what did I miss?

È stato utile?

Soluzione

Configure the relationship for only one entity (in your case, in UserProfileMap). Explicitly specify the property in the .WithRequired() call as well. Here's demo code that worked for me:

modelBuilder.Entity<SharedKeyRequired>()
    .HasOptional( skr => skr.SharedKeyOptional )
    .WithRequired( sko => sko.SharedKeyRequired );


public class SharedKeyRequired
{
    public int SharedKeyRequiredId { get; set; }

    public virtual SharedKeyOptional SharedKeyOptional { get; set; }
}

public class SharedKeyOptional
{
    public int SharedKeyOptionalId { get; set; }

    public virtual SharedKeyRequired SharedKeyRequired { get; set; }
}

Altri suggerimenti

Moho, I voted your answer as correct but I thought I would put MVC equivalent source here for those that might be confused by the verbage.

Desired end result is using the MVC AccountModel and adding code-first tables which have a foreignkey as their primary keys to extend the UserProfile table with an optional 1 to 1 relationship

Modify your user profile class to add a virtual reference to your new table

  [Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }

    public virtual UserInfo UserInfo { get; set; }
}

create your new table I chose to use Data Notation you could specify this in modelBuilder as modelBuilder.Entity().HasKey(k => k.UserId); modelBuilder.Entity().Property(ui => ui.UserId) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

 public class UserInfo
{
    [Key,ForeignKey("UserProfile")] //use above or specify this
    public int UserId { get; set; }
    public virtual UserProfile UserProfile { get; set; }
    public int somevalue { get; set; }
    public string name { get; set; }

}

override your OnModelCreating member of your context class and specify the relationship as Moho stated public class UsersContext : DbContext { public UsersContext() : base("DefaultConnection") { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       // modelBuilder.Entity<UserInfo>().HasKey(k => k.UserId);
       // modelBuilder.Entity<UserInfo>().Property(ui => ui.UserId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        modelBuilder.Entity<UserProfile>().HasOptional(ui => ui.UserInfo).WithRequired(up => up.UserProfile);
        base.OnModelCreating(modelBuilder);
    }


    public DbSet<UserProfile> UserProfiles { get; set; }
    public DbSet<UserInfo> UserInfoes { get; set; }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top