没有进入“为什么”,只需要继承并了解我必须使用的内容:)
我有一个映射到视图的EF6 edmx。其上没有标识列,因此为了使EF映射实体,选择第一个非空列作为PK。这背后的原始想法是只读不会进行更新或删除。没有过滤(ODATA位于此之上),而仅 - 我的意思是 - 使用的方式是来自实体的select top N *
。
视图中有4条记录。
TypeCode | Contact | UserID | LocaleID | EntityName
---------------------------------------------------------
1 6623 1032 9 Jane
1 6623 1032 9 Jane
1 6623 1032 9 John
1 6623 1032 9 John
我看到的问题是EF将所有4行映射相同。上面所有“约翰”的名字都变成了“简”
好的,抛开设计决策,并且视图上没有识别记录,为什么EF映射最后两行错误?我最初的想法是,因为“PK”设置为TypeCode
它不知道如何做到这一点。但是,为什么只在从数据库中读取结果时才使用键列?我原以为它只对更新和删除很重要
答案 0 :(得分:6)
如果按实体框架查询数据,则默认行为是每个实体化实体都由其唯一键跟踪。唯一键由您告知EF用作键的任何属性组成,或者,它可以推断为关键属性(在您的情况下为TypeCode
)。每当重复的实体密钥尝试进入更改跟踪器时,就会抛出一个错误,告知该对象已被跟踪。
因此,EF 无法实现具有重复主键值的对象。它会损害其跟踪机制。
看来,至少在EF6中,AsNoTracking()
可以用作解决方法。 AsNoTracking
告诉EF只是在不跟踪对象的情况下实现对象,因此它不会生成实体密钥。
我 现在,它在SQL查询结果中遇到其键值时,会静默返回同一个对象。这导致许多人感到困惑,直到最后。
顺便说一下,避免此问题的常用方法是在Sql Server中使用ROW_NUMBER
为视图生成临时唯一键值。这对于您在一个上下文实例中读取的只读数据来说已经足够了。