如何针对一个表映射多个实体?

时间:2013-09-04 14:07:40

标签: c# asp.net-mvc entity-framework

我正在尝试对同一个表使用两个不同的实体。拥有两个实体的目的是限制其中一个实体的属性数量,因为在其中一个编辑表单中,应该只能更改一些属性。

因此,为了避免将不可编辑的属性隐藏起来以保留其值,我认为只有一部分属性的单独实体是个好主意。

所以我有一个具有所有属性的实体,另一个只有一些属性。问题是我得到了这个例外:

  

`实体类型'ApplicationMapping'和'ApplicationMappingFull'   无法共享表'ApplicationMapping',因为它们不在   相同类型的层次结构或没有有效的一对一外键   与它们之间匹配主键的关系。

实体配置类如下所示:

class ApplicationMappingFullConfiguration : EntityTypeConfiguration<ApplicationMappingFull>  
{  
  public ApplicationMappingFullConfiguration()  
  {  
    ToTable("ApplicationMapping");  
    HasKey(p => p.Id);  
  }  
}  

class ApplicationMappingConfiguration : EntityTypeConfiguration<ApplicationMapping>  
{  
  public ApplicationMappingConfiguration()  
  {  
    ToTable("ApplicationMapping");  
    HasKey(p => p.Id);  
  }  
}

我如何实现我想要做的事情?有没有更好/更简单的方法呢?

谢谢!

4 个答案:

答案 0 :(得分:4)

我建议将单个实体映射到表,但创建两个“视图”实体,它们只包含表单所需的那些属性。

这些视图实体可以包含将输入的数据映射回底层实体的方法。

答案 1 :(得分:3)

您正在寻找的是TPH(Table Per Hierarchy)。这是一种关系继承模式,其中一个类及其所有子类共享同一个表,并且由Entity Framework本身支持。实际上,如果你所做的只是让一个实体从另一个实体继承,那么Entity Framework默认会部署这个模式。你根本不需要做任何特别的事情。

但是,有一个条件:由于基类上的属性必须足以能够将行成功保存到数据库,因此所有子类属性必须是可选的 - 至少在数据库级别上。您始终可以通过前端用户界面强制实施一个或多个属性。

<强>更新

扩展我在下面的评论,如果你要做的就是从表中返回一个数据子集,那么你已经拥有了所需的所有工具。您不需要两个单独的实体,只需要一个实体(在本例中为您的ApplicationMappingFull类),然后您可以使用LINQ仅返回所需的列。

db.ApplicationMappingFulls.Select(m => new ApplicationMappingViewModel
    {
        SomeProperty = m.SomeProperty,
        OtherProperty = m.OtherProperty
    });

在幕后,EF会发出一个只会选择SomePropertyOtherProperty列的查询,因为这就是所需要的。您的视图模型根本不会连接到EF;它只是一个保存EF返回的数据的类。

答案 2 :(得分:1)

另一种选择是让一个类派生自另一个,并隐藏或以其他方式中断您不希望允许编辑的字段。

作为一个例子......

class Full {
  public string ValueA {get;set;}
}

class Limited : Full {
  public new string ValueA {get; private set;}
}

这无疑是最好的解决方案,但您可以使用另一种选择。

答案 3 :(得分:-1)

你的问题有答案。

The entity types 'ApplicationMapping' and 'ApplicationMappingFull' cannot share table 'ApplicationMapping'

将实体类型映射到表时,您正在定义表的架构。如你所说,你有一个具有所有属性的实体,一个只有一些属性。将实体映射到表时,需要映射表的所有列。

所以在一行中,“这是不可能的”。

为了解决您的问题,您可以做Paddy建议的事情。否则,您可以创建具有最小必需属性的基类,然后扩展该类并添加其余属性。将模型传递给视图时,传递基类对象。但是,您可以在从数据库中获取记录时使用扩展类对象。