Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Id column issue

I have a problem with EF at the moment. I have an existing database and in there is a custom User table called Profiles. The user is below (I have stripped out most of the properties for easy reading).

public partial class Profile : IdentityUser
{
    public Profile()
    {
        this.Assets = new List<Asset>();

        // ...
    }

    public string CompanyId { get; set; }

    // ...

    public virtual Company Company { get; set; }
    public virtual ICollection<Asset> Assets { get; set; }

    // ...

}

and my DbContext looks like this (simplified):

public partial class SkipstoneContext : IdentityDbContext<Profile>
{
    static SkipstoneContext()
    {
        Database.SetInitializer<SkipstoneContext>(null);
    }

    public SkipstoneContext()
        : base("DefaultConnection")
    {
    }

    public DbSet<Asset> Assets { get; set; }

    // ...

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // ...

        modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
        modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
        modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
        modelBuilder.Entity<UserSecret>().HasKey<string>(r => r.UserName);
    }
}

And I have a class that looks like this:

    public Company()
    {
        this.Assets = new List<Asset>();
    }

    public string Id { get; set; }
    public string Name { get; set; }
    public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }
    public System.DateTime DateCreated { get; set; }
    public Nullable<System.DateTime> DateModified { get; set; }
    public bool Deleted { get; set; }

    public virtual Profile CreatedByProfile { get; set; }
    public virtual ICollection<Asset> Assets { get; set; }
}

The problem is that when I run my code, I get an error stating:

Invalid column name 'CreatedByProfile_Id'.

I need to tell the system that the Id column for my custom user is just Id. I had a mapping file:

public class ProfileMap : EntityTypeConfiguration<Profile>
{
    public ProfileMap()
    {
        // Primary Key
        this.HasKey(t => t.Id);

        // Properties
        this.Property(t => t.Id)
            .IsRequired()
            .HasMaxLength(128);

        this.Property(t => t.CompanyId)
            .IsRequired()
            .HasMaxLength(128);

        this.Property(t => t.CreatedBy)
            .IsRequired();

        this.Property(t => t.Title)
            .IsRequired();

        this.Property(t => t.Forename)
            .IsRequired();

        this.Property(t => t.Surname)
            .IsRequired();

        this.Property(t => t.Email)
            .IsRequired();

        this.Property(t => t.CredentialId)
            .IsRequired();

        // Table & Column Mappings
        this.ToTable("Profiles");
        this.Property(t => t.Id).HasColumnName("Id");
        this.Property(t => t.CompanyId).HasColumnName("CompanyId");
        this.Property(t => t.CreatedBy).HasColumnName("CreatedBy");
        this.Property(t => t.ModifiedBy).HasColumnName("ModifiedBy");
        this.Property(t => t.DateCreated).HasColumnName("DateCreated");
        this.Property(t => t.DateModified).HasColumnName("DateModified");
        this.Property(t => t.LastLoginDate).HasColumnName("LastLoginDate");
        this.Property(t => t.Title).HasColumnName("Title");
        this.Property(t => t.Forename).HasColumnName("Forename");
        this.Property(t => t.Surname).HasColumnName("Surname");
        this.Property(t => t.Email).HasColumnName("Email");
        this.Property(t => t.JobTitle).HasColumnName("JobTitle");
        this.Property(t => t.Telephone).HasColumnName("Telephone");
        this.Property(t => t.Mobile).HasColumnName("Mobile");
        this.Property(t => t.Photo).HasColumnName("Photo");
        this.Property(t => t.LinkedIn).HasColumnName("LinkedIn");
        this.Property(t => t.Twitter).HasColumnName("Twitter");
        this.Property(t => t.Facebook).HasColumnName("Facebook");
        this.Property(t => t.Google).HasColumnName("Google");
        this.Property(t => t.Bio).HasColumnName("Bio");
        this.Property(t => t.CompanyName).HasColumnName("CompanyName");
        this.Property(t => t.CredentialId).HasColumnName("CredentialId");
        this.Property(t => t.IsLockedOut).HasColumnName("IsLockedOut");
        this.Property(t => t.IsApproved).HasColumnName("IsApproved");
        this.Property(t => t.CanEditOwn).HasColumnName("CanEditOwn");
        this.Property(t => t.CanEdit).HasColumnName("CanEdit");
        this.Property(t => t.CanDownload).HasColumnName("CanDownload");
        this.Property(t => t.RequiresApproval).HasColumnName("RequiresApproval");
        this.Property(t => t.CanApprove).HasColumnName("CanApprove");
        this.Property(t => t.CanSync).HasColumnName("CanSync");
        this.Property(t => t.AgreedTerms).HasColumnName("AgreedTerms");
        this.Property(t => t.Deleted).HasColumnName("Deleted");
        this.Property(t => t.UserName).HasColumnName("UserName");

        // Relationships
        this.HasRequired(t => t.Company)
            .WithMany(t => t.Users)
            .HasForeignKey(d => d.CompanyId);

    }
}

but if I add that to my DbContext class I get an error stating:

A configuration for type 'Models.Profile' has already been added. To reference the existing configuration use the Entity() or ComplexType() methods.

I assume this is simple to fix, so could someone point me in the right direction please?

Cheers,

/r3plica

like image 959
r3plica Avatar asked Nov 01 '22 09:11

r3plica


1 Answers

The problem is at your Company class configuration. Try:

public class CompanyMap : EntityTypeConfiguration&ltCompany>
{
  public CompanyMap()
  {
    // Add this
    this.HasRequired(x => x.CreatedByProfile).WithMany().Map(
      x => x.MapKey("CreatedByProfileId"));

    // CreatedByProfileId is the FK column in the Company table that points
    // to the Profile table. This is my made up name for the column since
    // I don't know the real name in your database.
  }
}

If you don't have a configuration class for Company then in your OnModelCreating method you need:

modelBuilder.Entity&ltCompany>().HasRequired(x => x.CreatedByProfile).WithMany().Map(
  x => x.MapKey("CreatedByProfileId"));

UPDATE
Since you already have the property in your class.

modelBuilder.Entity&ltCompany>().HasRequired(
  x => x.CreatedByProfile).WithMany().HasForeignKey(x => x.CreatedBy);
like image 67
Arturo Martinez Avatar answered Nov 15 '22 03:11

Arturo Martinez