4

我正在使用EF 4.1 code first,我正在爲關聯實體掙扎,並獲取關聯表中設置的值。我試圖關注該帖子:Create code first, many to many, with additional fields in association table首先在實體框架代碼中檢索關聯表中的值

我的表如下所示(所有的都是複數形式):

表:產品

Id int 
Name varchar(50) 

表:規格

Id int 
Name varchar(50) 

表:ProductSpecifications

ProductId int 
SpecificationId int 
SpecificationValue varchar(50) 

我的相關類:

public class Product : IEntity 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<ProductSpecification> ProductSpecifications { get; set; } 
} 

public class Specification : IEntity 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<ProductSpecification> ProductSpecifications { get; set; } 
} 

public class ProductSpecification 
{ 
    public int ProductId { get; set; } 
    public virtual Product Product { get; set; } 
    public int SpecificationId { get; set; } 
    public virtual Specification Specification { get; set; } 
    public string SpecificationValue { get; set; } 
} 

我的上下文類:

public class MyContext : DbContext 
{ 
    public DbSet<Product> Products { get; set; } 
    public DbSet<Specification> Specifications { get; set; } 
    public DbSet<ProductSpecification> ProductSpecifications { get; set; } 

    protected override void OnModelCreating(DbModelBuilder dbModelBuilder) 
    { 
    } 
} 

我的倉庫方法,我做我的電話(不知道這是否是正確的):

public class ProductRepository : IProductRepository 
{ 
    MyContext db = new MyContext(); 

    public Product GetById(int id) 
    { 
      var product = db.Products 
       .Where(x => x.Id == id) 
       .Select(p => new 
       { 
        Product = p, 
        Specifications = p.ProductSpecifications.Select(s => s.Specification) 
       }) 
       .SingleOrDefault(); 

      return null; // It returns null because I don't know how to return a Product object? 
    } 
} 

這裏是錯誤,我回來了:

One or more validation errors were detected during model generation: 

System.Data.Edm.EdmEntityType: : EntityType 'ProductSpecification' has no key defined. Define the key for this EntityType. 
System.Data.Edm.EdmEntitySet: EntityType: EntitySet �ProductSpecifications� is based on type �ProductSpecification� that has no keys defined. 

這是什麼意思,沒有定義密鑰? ProductId和SpecificationId不會分別映射到產品的Id和規格的Id嗎?

我該如何返回單件產品的所有規格?

回答

1

實體框架將認識到ProductId外鍵屬性爲Product導航屬性和SpecificationId外鍵屬性爲Specification導航屬性。但是例外情況在您的ProductSpecification實體上抱怨缺少主鍵(「Key」=「主鍵」)。每個實體都需要定義一個關鍵屬性。這可以通過約定來實現 - 通過關鍵屬性的特定命名來實現 - 或者通過數據註釋或Fluent API來實現。

您的ProductSpecification類沒有EF根據慣例將其識別爲密鑰的屬性:否Id屬性和ProductSpecificationId(類名+「Id」)。

所以你必須明確地定義它。數據註釋定義其顯示在您鏈接的帖子:

public class ProductSpecification 
{ 
    [Key, Column(Order = 0)] 
    public int ProductId { get; set; } 
    public virtual Product Product { get; set; } 

    [Key, Column(Order = 1)] 
    public int SpecificationId { get; set; } 
    public virtual Specification Specification { get; set; } 

    public string SpecificationValue { get; set; } 
} 

而且在流利的API將是:

modelBuilder.Entity<ProductSpecification>() 
    .HasKey(ps => new { ps.ProductId, ps.SpecificationId }); 

兩種方式定義組合鍵,每個部分是一個外鍵到ProductSpecification表。 (您不需要明確定義FK屬性,因爲EF由於它們的約定友好名稱而識別它。)

您可以退貨,包括預先加載的所有規格,例如:

var product = db.Products 
    .Include(p => p.ProductSpecifications.Select(ps => ps.Specification)) 
    .SingleOrDefault(x => x.Id == id);