jvanrhyn
jvanrhyn

Reputation: 2824

Specifying the name of a column in Entity Framework for a Referenced Object

I have a pre-defined database that I want to map using Entity Framework 4 CodeFirst.

public class Site
{
    public int SiteId { get; set; }
    public string SiteName { get; set; }
    public DateTime InstallDate { get; set; }
    public string Phase { get; set; }
    public string Address { get; set; }
    public string GpsPosition { get; set; }
    public string NetworkDetail { get; set; }
    public string SiteCode { get; set; }
    public string UserGroupCode { get; set; }
    public string InfrastructureNumber { get; set; }
    public string Province { get; set; }

    public virtual ICollection<LcuSetting> LcuSettings { get; set; }
}

And another class

public class LcuSetting
{
    public int LCUSettingId { get; set; }
    [Column(Name="Site_Id")]
    public Site Site { get; set; }


    public string Name { get; set; }
    public string IPAddress { get; set; }
    public string SubnetMask { get; set; }
    public string DefaultGateway { get; set; }
}

Because of the mapping conventions of EF4 it is looking for a column SiteSiteId in the table LCUSettings, which it cannot find since the Column is actually named Site_ID

In my DbContext derived class I override the OnModelCreating method and set the tables names to use.

modelBuilder.Entity<Site>().ToTable("Site");

this works fine.

When I try to specify the column name however, as follows

modelBuilder.Entity<LcuSetting>().Property(c => c.Site).HasColumnName("Site_Id");

I receive the following exception message

The type 'LcuSystemOnline.Models.Site' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Data.Entity.ModelConfiguration.Configuration.Types.StructuralTypeConfiguration.Property(System.Linq.Expressions.Expression>)'

I understand the exception, but how do I how get the modelBuilder to assign a specific ColumnName to the Site

Upvotes: 7

Views: 10288

Answers (1)

Jeff
Jeff

Reputation: 106

In CTP5, you cannot use the Column attribute to specify the foreign key name that we create. You instead have to do it this way with the fluent API:

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Product> Products { get; set; }
}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Category Category { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Product>()
            .HasRequired(p => p.Category)
            .WithMany(c => c.Products)
            .IsIndependent()
            .Map(mc => mc.MapKey(c => c.Id, "CategoryId")); 
    }
}

Note the call to "Map" in the OnModelCreating method. This is something that a number of people have bumped into and I like the idea of using the ColumnAttribute to help with the name.

You can see this blog article I wrote for more details: http://blogs.msdn.com/b/adonet/archive/2010/12/10/code-first-mapping-changes-in-ctp5.aspx

Upvotes: 9

Related Questions