10

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

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

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

`实体类型'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

4 回答 4

4

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

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

于 2013-09-04T14:14:00.520 回答
3

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

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

更新

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

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

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

于 2013-09-04T14:39:51.183 回答
1

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

举个例子...

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

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

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

于 2015-04-23T16:15:35.300 回答
-1

你的问题有答案。

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

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

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

要解决您的问题,您可以按照 Paddy 的建议进行操作。否则,您可以创建具有最少必需属性的基类,然后扩展该类并添加剩余属性。在将模型传递给视图时,传递基类对象。但是,您可以在从数据库中获取记录时使用扩展类对象。

于 2013-09-04T14:15:18.017 回答