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

问题描述

我不知道如何映射在 EF 4.1 code先下下表,我需要重新presenting表哪些对象。我将如何获取该产品的规格列表?

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?

我目前只能有一个产品类。

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

修改

请看看我的更新原来的职位。我改变了产品和规格表的编号。

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 A值列,该列便含有100英寸值。我将如何修改code来检索这个值呢?我需要对我的看法显示出来。

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会创建这个映射连接表。如果你已经在数据库这样的表和它的命名并没有完全地按照实体框架的命名约定,你可以用流利的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");
        });

修改

您可以然后使用包括装载产品的规格例如:

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-第一的命名约定将承担建成的两个相关的类名的组合连接表的名称,然后复数它。因此,如果没有explicite映射到表名称 ProductSpecification EF将承担 ProductSpecifications (复数),并与该名建造查询作为表名。由于此表不存在于数据库中,你得到的异常的无效的对象名称dbo.SpecificationProducts。的当你运行一个查询。因此,您必须重命名数据库表中可以使用上面的映射code。

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

我会强烈建议使用explicite映射在任何情况下,因为连接表的名称EF假定depends在上下文的DbSets的顺序。通过改变这些设置的顺序连接表可能是 SpecificationProducts 。如果没有explicite映射到一个固定的表名集的背景下(通常是不重要的)交换可能会破坏你的工作的应用程序。

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 code映射关联表第一的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 23:52