首先在Entity Framework代码中检索关联表中的值

时间:2011-11-04 09:19:44

标签: entity-framework entity-framework-4 ado.net entity-framework-4.1

我正在使用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 个答案:

答案 0 :(得分:1)

实体框架将识别ProductIdProduct导航属性的外键属性,而SpecificationId外键 Specification导航属性的属性。但该异常会抱怨ProductSpecification实体上缺少主键(“Key”=“Primary Key”)。每个实体都需要定义一个关键属性。这可以通过约定 - 通过键属性的特定命名 - 或明确使用数据注释或Fluent API来实现。

您的ProductSpecification类没有按惯例将EF识别为关键字的属性:没有Id属性而没有ProductSpecificationId(类名+“Id”)。< / p>

所以你必须明确地定义它。使用数据注释定义它将显示在您链接的帖子中:

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; }
}

在Fluent 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);