首先在 EF 4.1 代码中映射关联表 [英] Mapping association tables in EF 4.1 code first

查看:21
本文介绍了首先在 EF 4.1 代码中映射关联表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定如何在 EF 4.1 code first 中映射下表以及我需要哪些对象来表示这些表.如何检索产品规格列表?

I'm not sure how to map the following tables below in EF 4.1 code first and what objects I need representing the tables. How would I retrieve a list of the product's specifications?

我目前只有一个 Product 类.

I currently only have a Product class.

Products Table:
Id
Name
IsActive

ProductSpecification Table:
ProductId
SpecificationId

Specifications Table:
Id
Name
IsActive

ProductSpecifications 是一个关联表.我的上下文类中还定义了以下内容:

ProductSpecifications is an association table. I also have the following defined in my context class:

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

编辑

请查看我更新的原始帖子.我更改了产品和规格表的 ID.

Please see my updated original post. I changed the Id of the Products and Specifications tables.

在我的上下文类中,我有以下内容:

In my context class I have the following:

public DbSet<Product> Products { get; set; }
public DbSet<Specification> Specifications { get; set; }

在我的存储库中,我有以下内容:

In my repository I have the following:

public Product GetById(int id)
{
     return db.Products
          .Include("Specifications")
          .SingleOrDefault(x => x.Id == id);
}

我的产品类(部分):

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

我的规范类:

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 的回答中所做的一切.我没有像他说的那样手动进行映射,但我首先需要了解以下内容:

This was all that I did from Slauma's answer. I did not do the mapping manually as what he said I should, but I first need to understand the following:

鉴于我上面的类和表,EF 4.1 命名约定究竟是如何处理关联表的?我问的原因是因为我的 GetById 方法中出现以下错误:

Given my classes and tables from above, what exactly does the EF 4.1 naming conventions state on how it handles association tables? The reason why I ask is because I get the following error in my GetById method:

Invalid object name 'dbo.SpecificationProducts'.

编辑 2

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

I forgot to mention the following :) A product can have a specification height as value. And for this height I need to specify a value. Like 100 inches. So I modified the ProductSpecifications table to have a value column called SpecificationValue, this column will contain the value 100 inches. How would I modify the code to retrieve this value as well? I need to display it on my view.

推荐答案

在多对多关系中,您只需为要关联的实体定义类,而不为关联表定义实体.此表在您的模型中隐藏"并由实体框架自动管理.所以你可以定义这些类:

In a many-to-many relationship you only define classes for the entities you want to associate but not an entity for the association table. This table is "hidden" in your model and managed by Entity Framework automatically. So you can define these classes:

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 中手动定义映射:

This is usually enough to define a many-to-many relationship. EF would create a join table from this mapping. If you already have such a table in the database and its naming doesn't follow exactly the naming conventions of Entity Framework you can define the mapping manually in 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 加载产品的规格,例如:

You can then load the specifications of a product by using Include for example:

var productWithSpecifications = context.Products
    .Include(p => p.Specifications)
    .SingleOrDefault(p => p.ProductId == givenProductId);

这会将产品与规格一起加载.如果您只想要给定产品 ID 的规格,您可以使用以下内容:

This would load the product together with the specifications. If you only want the specifications for a given product id you can use the following:

var specificationsOfProduct = context.Products
    .Where(p => p.ProductId == givenProductId)
    .Select(p => p.Specifications)
    .SingleOrDefault();

...返回规范的集合.

...which returns a collection of specifications.

编辑 2

EF Code-First 的命名约定将假定连接表的名称由两个相关的类名称组合而成,然后将其复数.因此,如果没有到您的表名 ProductSpecification 的显式映射,EF 将假定 ProductSpecifications (复数)并使用该名称作为表名构建查询.由于该表在数据库中不存在,因此您在运行查询时会收到异常Invalid object name 'dbo.SpecificationProducts'.".所以,你必须要么重命名数据库中的表,要么使用上面的映射代码.

The naming conventions of EF Code-First will assume a name of the join table built as combination of the two related class names and then pluralize it. So, without the explicite mapping to your table name ProductSpecification EF would assume ProductSpecifications (Plural) and build queries with that name as table name. Because this table doesn't exist in the database you get the exception "Invalid object name 'dbo.SpecificationProducts'." when you run a query. So, you must either rename the table in the database or use the mapping code above.

编辑 3

我强烈建议在任何情况下都使用显式映射,因为连接表名称 EF 假定 取决于您的上下文中 DbSet 的顺序.通过改变这些集合的顺序,连接表可以是SpecificationProducts.如果没有到固定表名的显式映射,上下文中的集合交换(通常不重要)可能会破坏您的工作应用程序.

I would strongly recommend to use the explicite mapping in any case because the join table name EF assumes depends on the order of the DbSets in your context. By changing the order of those sets the join table could be SpecificationProducts. Without the explicite mapping to a fixed table name a (usually unimportant) swapping of the sets in the context could break your working application.

这篇关于首先在 EF 4.1 代码中映射关联表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆