EF code first - composite key

岁酱吖の 提交于 2019-12-06 07:23:52

问题


I have a legacy database which has two collumns and I want to map them as 1 ID is this possible

for example

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

then my Modelbinder looks like this

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

What I need would be something like ProductID = ShortDescription + UserName in the mapping... because these two collumns share a unique key contraint...

Don't know if this makes sens but any suggestions would be great... Please don't ask about the database design => this is like it is and should not be changed... that's why I thought EF code-first could help me (hope cross fingers)... because it looks like the db hasn't got pk defined just unique key constraints...

anyway ... help would be terrific..


回答1:


Sounds like you want a complex type AND want the complex type to be recognized as the key by using the convention of appending ID on the end of the property name.

EF CF can't do that at this point.

You can tell EF CF about a composite key through the Key attribute or FluentAPI.

Data Annotation:

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

Fluent API:

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

You can create a complex type that you can use in your code to work more the way you want your code to work conceptually.

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

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

Then to map it using the Fluent API:

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

Or if you want to use Data Annotations:

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

You have to specify the column names or the configuration is going to assume the column names are ProductID_ShortDescription....

Here's some more info on Complex Types.




回答2:


Actually, you want to map a single conceptual property to a couple of storage columns. There is a code that will concatenate the values from columns into property, so far so good.
But let's imagine the process of adding a new Entity to the context. So, we have set a value for the property. How should EF know the rule to write the value of this property to both columns?
Not sure this scenario is possible to implement.



来源:https://stackoverflow.com/questions/3398487/ef-code-first-composite-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!