First, the EF code - composite key

c# code-first entity-framework

Question

I want to transfer two columns in a historical database into a single ID. Is this possible?

for instance

    public class Product
{ 
public string ProductID {get;set;}
public string ShortDescription {get;set;}
public string UserName {get;set;}
}

and this is how my Modelbinder appears.

modelBinder.Entity<Product>().
HasKey(p=>p.ProductID)
.MapSingle(product =>
new {
 colShotDesc = product.ShortDescription,
 colUser = product.UserName
}
).ToTable("Products");

Because these two columns share a single key constraint, what I need in the mapping is something like ProductID = ShortDescription + UserName.

I'm not sure whether this makes sense, but any advice would be much appreciated. Please don't inquire about the database architecture; it is what it is and shouldn't be altered. Because it seems that the database only has unique key constraints established, I thought EF code-first would be able to assist me.

Any assistance would be much appreciated.

1
3
8/3/2010 4:16:00 PM

Popular Answer

By adding ID to the end of the property name, it seems that you both want a complex type and want the complex type to be recognized as the key.

EF CF is currently unable to achieve that.

A composite key may be disclosed to EF CF via the Key property or FluentAPI.

Annotation of Data:

public class Product 
{  
  [Key, Column(Order=0)]
  public string ShortDescription {get;set;} 
  [Key, Column(Order=1)]
  public string UserName {get;set;} 
}

Fluid API

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  modelBuilder.Entity<Product>()
               .HasKey(p=> new{p.ShortDescription, p.UserName});
}

You may design a complicated type that you can utilize in your code to make it function more conceptually the way you want it to.

public class Product 
{  
  public ProductID Key {get;set;}
}

public class ProductID 
{
  public string ShortDescription {get;set;} 
  public string UserName {get;set;} 
}

Using the Fluent API, map it after that:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  modelBuilder.ComplexType<ProductID>()
               .Property(p=>p.ShortDescription)
               .HasColumnName("ShortDescription")
               .Property(p=>p.UserName)
               .HasColumnName("UserName");
}

Alternatives include using Data Annotations:

[ComplexType]
public class ProductID
{
  [Column("ShortDescription")]
  public string ShortDescription {get;set;} 
  [Column("UserName")]
  public string UserName {get;set;} 
}

If you don't give the column names, the setup will use ProductID ShortDescription as the default.

Here is additional information about Complex Types.

11
4/16/2011 2:16:00 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow