我的数据库中有一个包含很多字段的表。 大部分时间我都需要所有这些字段。然而,有一种情况,我只需要一些字段,而且我正在加载大量的行。
我想要做的是手动添加实体,然后简单地将其映射到原始表,但删除我不需要的列。我把这一切都搞定了,但我得到了一个相当不言自明的错误:
映射片段的问题 ... EntitySets'FmvHistoryTrimmed'和 'FMVHistories'都映射到 表'FMVHistory'。他们的主要钥匙 可能会发生碰撞。
还有其他方法可以解决这个问题吗?同样,大部分时间都使用了所有列,因此我不想减少原始实体并将“额外”字段放入复杂类型中。
答案 0 :(得分:34)
您无法将两个常规实体映射到同一个表中。你有几个选择:
表格拆分
Table splitting允许您将表映射为1:1关系的两个实体。第一个实体将仅包含您需要的PK和字段子集。第二个实体将包含所有其他字段和PK。两个实体都将包含彼此的导航属性。现在,如果您只需要字段子集,则可以查询第一个实体。如果您需要所有字段,您将查询第一个实体并将navifation属性包含到第二个实体。如果需要,您还可以延迟加载第二个实体。
<强> QueryView 强>
QueryView是直接在映射(MSL)中定义的ESQL查询,它被映射到新的只读实体类型。您可以使用QueryView定义完整实体到子实体的投影。必须在EDMX中手动定义QueryView(它在设计器中不可用)。据我所知,CodeView在Code中不可用,但它实际上与自定义投影到非实体类型相同。
<强> DefiningQuery 强>
DefiningQuery是直接在您的存储模型(SSDL)中定义的自定义查询。定义查询通常在映射到数据库视图时使用,但您可以将其用于任何自定义SQL SELECT。您将查询结果映射到只读实体类型。必须在EDMX中手动定义DefiningQuery(在设计器中不可用)。它在Code中也不是直接可用的,但实际上与在SqlQuery
上调用DbDatabase
相同。 DefiningQuery的问题在于,一旦在SSDL中手动定义它,就无法使用数据库中的更新模型,因为此操作会替换完整的SSDL并删除您的查询定义。
答案 1 :(得分:8)
我会在数据库上创建一个仅包含所需数据的视图,并将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
});
}