将两个不同的实体映射到同一个表?

Ada*_*kis 38 entity-framework entity-framework-4

我的数据库中有一个包含很多字段的表. 大多数时候我需要所有这些领域.然而,有一种情况,我只需要一些字段,而且我正在加载大量的行.

我想要做的是手动添加一个实体,然后简单地将其映射到原始表,但删除我不需要的列.我把这一切都搞定了,但我得到了一个相当不言自明的错误:

映射片段的问题...... EntitySets的'FmvHistoryTrimmed'和'FMVHistories'都映射到表'FMVHistory'.他们的主键可能会发生碰撞.

我还有其他方法可以解决这个问题吗?同样,大多数时候都使用了所有列,所以我不想减少原始实体并将"额外"字段放入复杂类型中.

Lad*_*nka 34

您不能将两个常规实体映射到同一个表中.你有几个选择:

  1. 使用表拆分.
  2. 使用自定义查询和非实体类型的投影(如@Aducci建议)
  3. 使用QueryView
  4. 使用数据库视图或直接使用DefiningQuery

表拆分

表拆分允许您将表映射为1:1关系的两个实体.第一个实体将仅包含您需要的PK和字段子集.第二个实体将包含所有其他字段和PK.两个实体都将包含彼此的导航属性.现在,如果您只需要字段子集,则可以查询第一个实体.如果您需要所有字段,您将查询第一个实体并将navifation属性包含到第二个实体.如果需要,您还可以延迟加载第二个实体.

QueryView

QueryView是直接在映射(MSL)中定义的ESQL查询,它映射到新的只读实体类型.您可以使用QueryView定义完整实体到子实体的投影.必须在EDMX中手动定义QueryView(它在设计器中不可用).据我所知,CodeView在Code中不可用,但实际上与非实体类型的自定义投影相同.

DefiningQuery

DefiningQuery是直接在存储模型(SSDL)中定义的自定义查询.定义查询通常在映射到数据库视图时使用,但您可以将其用于任何自定义SQL SELECT.您将查询结果映射到只读实体类型.必须在EDMX中手动定义DefiningQuery(在设计器中不可用).它也不能直接在代码avaliable第一,但它实际上是一样的调用SqlQueryDbDatabase.DefiningQuery的问题在于,一旦在SSDL中手动定义它,就无法使用数据库中的更新模型,因为此操作会替换完整的SSDL并删除您的查询定义.


Adu*_*cci 8

我将在数据库上创建一个仅包含所需数据的View,并将View添加到您的实体数据模型中.

如果您不想修改数据库,则可以创建一个Linq to entities或ESQL语句,仅使用您需要的信息投影到POCO类.

public IQueryable<SimpleObject> GetView(DBContext context)
{
    return  (from obj in context.ComplexObjects
            select new SimpleObject() { Property1 = obj.Property1,
                                        Property1 = obj.Property2
                                      }); 
}
Run Code Online (Sandbox Code Playgroud)