zoukankan      html  css  js  c++  java
  • Linq to Sql 或linq to entities 与SQL查询结果不一致 返回重复结果问题

    用Entity Framework开发项目过程中,发现linq查询返回的结果,与SQL查询出的结果不一致。

    问题表现为: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 = db.entity.select(v=>v);//entity为实体对象

    得出的结果为:

    ====LINQ返回错误的结果=====

    列1(key列) 列2 列3

    1             a1    a1         

    1             a1    a1  (这行是错误的)

    3             a3    a3

    问题分析:

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

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

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

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

    如果LINQ的查询还附加排序也会影响LINQ查询的结果,总之会返回不同的错误结果 

    解决方法:

    1.找出视图中可以用来唯一标识该行记录的那些列,在edmx中将它们设为实体键(Key列),在我的项目中还给这个字段加了唯一键约束,防止LINQ查询结果出错。

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

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

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

    比如有一个视图View2的创建语句如下:

    select col1,col2,col3,count(col4) as col4 from [table] group by col1,col2,col3

    此时为了避免错误的结果,有些朋友,就把视图中col1,col2,col3的列都设为实体键,这样的确可以避免一些问题,有时候列太多了,全设为实体键,不是一个好办法。

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

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

    然后将index列设为实体键就OK了。

    2.使用EF执行SQL语句的方法 DbContext.Database.SqlQuery<T>(视图名),也可以解决问题,效率就不用我说,通过SQL Server Profiler跟踪测试一下就知道了。

    本文参考了TobeorNot的经验加补充,如有更好的方法,请指教。

  • 相关阅读:
    cordova 日曆 聯系人 插件使用
    ionic 不同view的數據交互
    JQuery iframe 刷新效果
    fis学习
    如何用nfs命令烧写内核和文件系统(网络下载文件到nandflash)(未完)
    布线的基本原则
    电平转转换电路
    焊盘的制作
    flash-热风焊盘的制作
    焊盘的层面剖析
  • 原文地址:https://www.cnblogs.com/sa9527/p/5054714.html
Copyright © 2011-2022 走看看