我首先使用EF 4.1代码,我正在努力与关联实体并获取在关联表中设置的值.我试着关注帖子: Create code first, many to many, with additional fields in association table. 我的表格如下(全部为复数形式):
我的表格如下(全部为复数形式):
表:产品
Id int Name varchar(50)
表:规格
Id int Name varchar(50)
表:产品规格
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吗?
我如何退回具有所有规格的单一产品?
实体框架将识别ProductId是Product导航属性的外键属性,而SpecificationId是Specification导航属性的外键属性.但该异常会抱怨您的ProductSpecification实体上缺少主键(“Key”=“Primary Key”).每个实体都需要定义一个关键属性.这可以通过约定 – 通过键属性的特定命名 – 或明确使用数据注释或Fluent API来实现.您的ProductSpecification类没有EF会按惯例识别为键的属性:No 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; } }
在Fluent API中,它将是:
modelBuilder.Entity<ProductSpecification>() .HasKey(ps => new { ps.ProductId, ps.SpecificationId });
两种方式都定义了一个复合键,每个部分同时是Product或Specification表的外键. (您不需要明确定义FK属性,因为EF因其常规友好名称而识别它.)
您可以退回包含所有规格的产品,例如:
var product = db.Products .Include(p => p.ProductSpecifications.Select(ps => ps.Specification)) .SingleOrDefault(x => x.Id == id);