Linq 使用entity framework查询视图返回重复记录的问题(转)

最近用Entity Framework开发项目过程中,发现linq查询返回的结果,与SQL语句查询出的正确结果不一致。LINQ查询出来的结果是一些重复记录。

这种问题一般是对数据库视图进行查询时发生,问题产生的原因及现象如下:

1)使用.net 的linq to sql,或linq to entities 生成的实体对象,出于为提高效率等原因,会对每个对象自动判断出一些列做为实体对象的Key(EntityKey),

这个Key就是相当于我们表中的主键,查询结果时,会根据这个Key列的值进行判断,假设数据库中有视图View1有3条记录如下:

View1=

列1(key列) 列2 列3

1 a1 a1

1 a2 a2

3 a3 a3

2)假设此View1的实体对象中,列1判断为Key列(标识列),如果当前我们有一个如下的查询,SQL语句如下:

SELECT 列1,列2,列3 FROM [View1]

显然,查询出来正确的结果为:

SQL返回正确的结果=

列1(key列) 列2 列3

1 a1 a1

1 a2 a2

3 a3 a3

3)但是如果你用LINQ语句去查:var objs = objs.entities.select(v=>v);//entities为实体集对象

得出的结果为:

LINQ返回错误的结果=

列1(key列) 列2 列3

1 a1 a1

1 a1 a1 (这行是错误的)

3 a3 a3

问题分析:

我们会发现,第2条记录与第一条记录是一样的,原因就在于实体对象中的Key列即列1的值相同(在我们的例子中都为1),

那么LINQ返回第一条数据时,没有问题,正常返回;

返回第二条时,判断Key列的值,发现都为1,那么就认为第二条数和第一条数据是一样的,所以直接返回第一行记录的值,做为第二条记录。

第三条记录,key列不同,取回正确数据。

解决方法:

找出视图中可以用来唯一标识该行记录的那些列,将它们设为实体键(Key列)。

通过上面分析,我们就可以明白为什么出现这种问题都是在使用视图的时候,因为如果是表的话,那么基本上主键会被判断为实体对象的Key,显示不会出现数据重复问题。

但是视图就不一样,特别是一些GroupBy语句创建的视图,.net底层自动判定的EntityKey,就会有问题,一般都是随便找一个或者几个列,GroupBy 语句的视图中,

基本上没有哪一个或者哪几个字段能做为记录唯一标识,那么我们只能给记录生成标识列来解决。

但是,我们可以给记录自动生成列,就是使用 row_number() 或者 newid() 方法,比如可以使用如下语句创建视图:

select [index]=row_number() over (order by ID), col1,col2,col3,count(col4) as col4 from [table] group by col1,col2,col3

然后在 .edmx 中将index列设为实体键(entity key=true)。

转自:https://www.cnblogs.com/shoter193/p/3631301.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值