TheCloudlessSky
TheCloudlessSky

Reputation: 18353

Code-First CTP5 navigational properties generates wrong column names

I have the following model and configuration:

public class User
{
    public int Id { get; set; }
    public User CreatedBy { get; set; }
    public DateTime? DateCreated { get; set; }
    public string Name { get; set; }
    public string Username { get; set; }
}

public class UserConfiguration : EntityTypeConfiguration<User>
{
    public UserConfiguration()
    {
        this.HasKey(t => t.Id);

        this.HasOptional(u => u.CreatedBy);
        this.Property(u => u.DateCreated);

        this.Property(u => u.Name).HasMaxLength(64);
        this.Property(u => u.Username).HasMaxLength(64);
    }
}

public class SampleContext : DbContext
{

    public IDbSet<User> Users { get; set; }

    public SampleContext(string dbConnection)
        : base(dbConnection)
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new UserConfiguration());
    }
}

I can work with the context and add users just fine. I then was looking at the table generated by Code First and realized that the CreatedBy property isn't generating a CreatedById column but rather a UserId column. If I add another property such as ModifiedBy it will generate UserId1 and so on:

alt text

I tried mapping with HasRequired() as well but the property still generates a column name that matches the actual type and not the property name. Any help would be appreciated.

Upvotes: 1

Views: 508

Answers (3)

Morteza Manavi
Morteza Manavi

Reputation: 33216

You basically want to create a Self-Reference Independent Association with a custom Foreign Key column name and here is the fluent API code to do this:

public UserConfiguration()
{
    this.HasRequired(u => u.CreatedBy)
        .WithMany()
        .IsIndependent()
        .Map(m => 
        {
            m.MapKey(u => u.Id, "CreatedById");
        });
}

However, this code throws an exception due to a bug in CTP5. Hence, for the time being, you can use the suggested workaround in MSDN forum (changing your independent association to FK association and explicitly name your FK property) and save this code for the RTM next year.

Upvotes: 1

Steven K.
Steven K.

Reputation: 2106

You can overrule the default column names using HasColumnName(...)

public class UserConfiguration : EntityTypeConfiguration<User>
{
    public UserConfiguration()
    {
         this.HasKey(t => t.Id);

         this.HasOptional(u => u.CreatedBy);
         // Map the 'DateCreated' Property to the 'CreatedById' table field.
         this.Property(u => u.DateCreated).HasColumnName("CreatedById");

         this.Property(u => u.Name).HasMaxLength(64);
         this.Property(u => u.Username).HasMaxLength(64);
     }
 }

Upvotes: 0

TheCloudlessSky
TheCloudlessSky

Reputation: 18353

I cross posted this on the MSDN forums and I guess that this is, so far, by design. All navigational properties generate the type name + Id for the column name. To me this is a fundamental design flaw in code-first. The names generated don't even reflect the column (except that it's a User).

Upvotes: 0

Related Questions