entity-framework - 首先在EF 4.1代码中映射关联表

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

我不确定如何在EF 4.1 code first中映射以下表格以及我需要代表哪些对象的表格。我将如何检索产品规范列表?

我目前只有Product类。

Products Table:
Id
Name
IsActive

ProductSpecification Table:
ProductId
SpecificationId

Specifications Table:
Id
Name
IsActive
ProductSpecifications是一个关联表。我的上下文类中还定义了以下内容:
public DbSet<Product> Products { get; set; }

编辑

请参阅我更新的原始帖子。我更改了产品和规范表的ID。

在我的上下文类中,我有以下内容:
public DbSet<Product> Products { get; set; }
public DbSet<Specification> Specifications { get; set; }

在我的存储库中,我有以下内容:
public Product GetById(int id)
{
     return db.Products
          .Include("Specifications")
          .SingleOrDefault(x => x.Id == id);
}

我的Product class(部分):
public class Product : IEntity
{
     public int Id { get; set; }
     public string Name { get; set; }
     public bool IsActive { get; set; }
     public ICollection<Specification> Specifications { get; set; }
}

我的Specification class:
public class Specification : IEntity
{
     public int Id { get; set; }
     public string Name { get; set; }
     public bool IsActive { get; set; }
     public ICollection<Product> Products { get; set; }
}

这就是我根据Slauma的回答所做的所有事情。我没有按照他所说的那样手动进行映射,但是我首先需要了解以下内容:

从上面给出我的类和表,EF 4.1命名约定在处理关联表的方式上到底做了什么规定?我问的原因是因为我的GetById方法中出现以下错误:
Invalid object name 'dbo.SpecificationProducts'.

编辑2

我忘记提及以下内容:)产品可以具有规范高度作为值。对于这个高度,我需要指定一个值。像100英寸。因此,我修改了ProductSpecifications表,使其具有一个名为SpecificationValue的值列,该列将包含100英寸的值。我将如何修改代码以检索此值?我需要在我的 View 上显示它。

最佳答案

在多对多关系中,您只为要关联的实体定义类,而没有为关联表定义实体。该表在模型中“隐藏”,并由Entity Framework自动管理。因此,您可以定义以下类:

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }

    public ICollection<Specification> Specifications { get; set; }
}

public class Specification
{
    public int SpecificationId { get; set; }
    public string Name { get; set; }

    public ICollection<Product> Products { get; set; }
}

通常,这足以定义多对多关系。 EF将根据该映射创建一个联接表。如果数据库中已经有这样一个表,并且其命名不完全符合Entity Framework的命名约定,则可以在Fluent API中手动定义映射:
modelBuilder.Entity<Product>()
    .HasMany(p => p.Specifications)
    .WithMany(s => s.Products)
    .Map(c =>
        {
            c.MapLeftKey("ProductId");
            c.MapRightKey("SpecificationId");
            c.ToTable("ProductSpecification");
        });

编辑

然后,您可以使用Include加载产品的规范,例如:
var productWithSpecifications = context.Products
    .Include(p => p.Specifications)
    .SingleOrDefault(p => p.ProductId == givenProductId);

这将把产品和规范一起装载。如果只需要给定产品ID的规范,则可以使用以下内容:
var specificationsOfProduct = context.Products
    .Where(p => p.ProductId == givenProductId)
    .Select(p => p.Specifications)
    .SingleOrDefault();

...这会返回规范的集合。

编辑2

EF Code-First的命名约定将假设连接表的名称是作为两个相关类名称的组合而构建的,然后对其进行复数处理。因此,如果没有显式映射到表名ProductSpecification,EF会假设使用ProductSpecifications(复数)并使用该名称作为表名来构建查询。由于该表在数据库中不存在,因此会出现异常“无效的对象名称'dbo.SpecificationProducts'”。当您运行查询时。因此,您必须重命名数据库中的表或使用上面的映射代码。

编辑3

我强烈建议在任何情况下都使用显式映射,因为联接表名称EF假定为depends on the order of the DbSets in your context。通过更改这些集合的顺序,联接表可以为SpecificationProducts。如果没有显式映射到固定的表名,则在上下文中(通常不重要)交换集合可能会破坏您的工作应用程序。

关于entity-framework - 首先在EF 4.1代码中映射关联表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7965972/

相关文章:

c# - 违反 PRIMARY KEY 约束。无法插入重复键

c# - Entity Framework 与有时独立的类一对一

c# - 有条件的分组、求和、相减

c# - 寻求一种成本较低的解决方案来匹配两个表的 ID

c# - 在 SQLite 中启用外键约束

entity-framework - Entity Framework : Querying Child Entities

c# - 作为静态或非静态类的存储库?

c# - 尝试填充列表对象时出现 fatal error

c# - 将大量数据复制到 SQL CE 数据库中

c# - 是否可以首先在 Entity Framework 代码中使用 PK 列作为鉴别器?