今天拿Entity Framework改写早期的一个项目,涉及到对NULL值处理的时候,遇到了点问题,就是如何查询数据库中某字段为NULL的记录,写了几个测试用的例子,然后用SQL Server Profiler抓SQL。


测试1:直接使用null

  1. var clients = ctx.Clients.Where(c => c.ParentGUID == null);

对应的SQL是:

  1. -- 执行正常
  2. SELECT 
  3. [Extent1].[GUID] AS [GUID], 
  4. [Extent1].[Name] AS [Name], 
  5. [Extent1].[ParentGUID] AS [ParentGUID]
  6. FROM [dbo].[Clients] AS [Extent1]
  7. WHERE [Extent1].[ParentGUID] IS NULL



测试2:使用等于null的变量:

  1. string parentGuid = null;
  2. var clients = ctx.Clients.Where(c => c.ParentGUID == parentGuid);

对应的SQL是:

  1. -- 使用了值为NULL的变量,但是用了等号,所以取不到值了
  2. exec sp_executesql N'SELECT 
  3. [Extent1].[GUID] AS [GUID], 
  4. [Extent1].[Name] AS [Name], 
  5. [Extent1].[ParentGUID] AS [ParentGUID]
  6. FROM [dbo].[Clients] AS [Extent1]
  7. WHERE [Extent1].[ParentGUID] = @p__linq__0',N'@p__linq__0 varchar(8000)',@p__linq__0=NULL



测试3:加判断

  1. string parentGuid = null;
  2. var clients = ctx.Clients.Where(c => c.ParentGUID == (string.IsNullOrEmpty(parentGuid) ? null : parentGuid));

  对应的SQL是:

  1. -- 无语了,这也整得太复杂了吧,显然得不到正确结果
  2. exec sp_executesql N'SELECT 
  3. [Extent1].[GUID] AS [GUID], 
  4. [Extent1].[Name] AS [Name], 
  5. [Extent1].[ParentGUID] AS [ParentGUID]
  6. FROM [dbo].[Clients] AS [Extent1]
  7. WHERE [Extent1].[ParentGUID] = (
  8.     CASE 
  9.         WHEN ((@p__linq__0 IS NULL) OR (( CAST(LEN(@p__linq__0) AS int)) = 0)) 
  10.         THEN CAST(NULL AS varchar(1)) 
  11.         ELSE @p__linq__1 
  12.     END
  13. )',N'@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000)',@p__linq__0=NULL,@p__linq__1=NULL



测试4:另一种方式加判断

  1. string parentGuid = null;
  2. var clients = ctx.Clients.Where(c => string.IsNullOrEmpty(parentGuid) ? c.ParentGUID == null : c.ParentGUID == parentGuid);

对应的SQL是:

  1. --继续无语,比刚才的还复杂,同样得不到正确结果
  2. exec sp_executesql N'SELECT 
  3. [Extent1].[GUID] AS [GUID], 
  4. [Extent1].[Name] AS [Name], 
  5. [Extent1].[ParentGUID] AS [ParentGUID]
  6. FROM [dbo].[Clients] AS [Extent1]
  7. WHERE (
  8.     CASE 
  9.         WHEN ((@p__linq__0 IS NULL) OR (( CAST(LEN(@p__linq__0) AS int)) = 0)) 
  10.         THEN cast(0 as bit) 
  11.         
  12.         WHEN ([Extent1].[ParentGUID] = @p__linq__1) 
  13.         THEN cast(1 as bit) 
  14.         
  15.         WHEN ([Extent1].[ParentGUID] <> @p__linq__1) 
  16.         THEN cast(0 as bit) 
  17.     END
  18. ) = 1',N'@p__linq__0 nvarchar(4000),@p__linq__1 varchar(8000)',@p__linq__0=NULL,@p__linq__1=NULL

晕倒,看来把Linq的思想直接往EF上套是行不通的,某些情况下差异还是挺大的。

转:Entity Framework对NULL值的处理的更多相关文章

  1. Entity Framework的默认值BUG解决方法

    在使用.Net 3.5里的Entity Framework开发网站的时候,遇到了一个问题:添加记录时,对于DateTime型的数据,无法使用数据库的默认值. 具体的情况是这样的,我的数据库有个User ...

  2. 《Entity Framework 6 Recipes》中文翻译系列 (14) -----第三章 查询之查询中设置默认值和存储过程返回多结果集

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 3-6在查询中设置默认值 问题 你有这样一个用例,当查询返回null值时,给相应属性 ...

  3. decimal类型不能为空,自定义update更新null值的问题。

    if (!string.IsNullOrEmpty(yt_time_limit_1)) { entity["yt_time_limit_1"] = Convert.ToDecima ...

  4. 《Entity Framework 6 Recipes》中文翻译系列 (10) -----第二章 实体数据建模基础之两实体间Is-a和Has-a关系建模、嵌入值映射

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 2-11 两实体间Is-a和Has-a关系建模 问题 你有两张有Is-a和Has-a ...

  5. 《Entity Framework 6 Recipes》中文翻译系列 (44) ------ 第八章 POCO之POCO中使用值对象和对象变更通知

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 8-4  POCO中使用值对象(Complex Type--也叫复合类型)属性 问题 ...

  6. 转载Entity Framework 4.1 DbContext使用记之三——如何玩转实体的属性值?

    Entity Framework 4.1 DbContext使用记之一——如何查找实体? DbSet.Find函数的使用与实现 Entity Framework 4.1 DbContext使用记之二— ...

  7. Entity Framework Core的贴心:优雅处理带默认值的数据库字段

    对于用于保存记录添加时间的数据库日期字段,我们通常会设置一个 GETDATE() 的默认值,而不是在应用程序的代码中获取当前时间进行保存,这样可以避免由于web服务器时钟不同步引起的时间偏差. Ent ...

  8. 关于Entity Framework更新的几种方式以及可能遇到的问题(附加类型“Model”的实体失败,因为相同类型的其他实体已具有相同的主键值)在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值,则可能会发生上述行为

    在日常使用Entity Framework中,数据更新通常会用到.下面就简单封装了一个DBContext类 public partial class EFContext<T> : DbCo ...

  9. Entity Framework添加记录时获取自增ID值

    与Entity Framework相伴的日子痛并快乐着.今天和大家分享一下一个快乐,两个痛苦. 先说快乐的吧.Entity Framework在将数据插入数据库时,如果主键字段是自增标识列,会将该自增 ...

随机推荐

  1. Javascript nextElementSibling和nextSibling

    function next(ele) { if (typeof ele.nextElementSibling == 'object') { return ele.nextElementSibling; ...

  2. BZOJ 1015: [JSOI2008]星球大战starwar 并查集

    1015: [JSOI2008]星球大战starwar Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝 ...

  3. 15.RDD 创建内幕解析

    第15课:RDD创建内幕 RDD的创建方式 Spark应用程序运行过程中,第一个RDD代表了Spark应用程序输入数据的来源,之后通过Trasformation来对RDD进行各种算子的转换,来实现具体 ...

  4. android学习--radiogroup学习

    这个阶段在学习android的相关基本UI现将相关练习的代码粘贴在此便于后期学习之用(radio控件) 效果图:   main_layout.xml <?xml version="1. ...

  5. session原理总结

    session原理总结 session多服务器共享的方案梳理 session原理 session的工作原理 客户端禁用cookie时session解决方案[转]

  6. React属性的3种设置方式

    一. 不推荐用setProps,因为以React的设计思想相悖,推荐以父组件向子组件传递属性的方式 二.3种用法的代码 1.键值对 <!DOCTYPE html> <html lan ...

  7. MyBatis学习总结_12_Mybatis+Mysql分页查询

    package cn.tsjinrong.fastfile.util; /** * @ClassName: Page * @Description: TODO(分页组件的父类,用来封装分页的 通用内容 ...

  8. activeMQ主要的几类集群部署方式

    官方主从实现的文档:http://activemq.apache.org/masterslave.html   一.activeMQ主要的几类部署方式比较 1.默认的单机部署(kahadb) acti ...

  9. openstack配置注意事项(主要是网络相关)

    vlan协议应该配置为802.1q,另一个容易混淆的为ISL,配置命令为 switchport trunk encapsulation dot1q /islswitchport mode trunk ...

  10. linux c 生成uuid

    /********方法一**********/#include <stdio.h> #include <stdlib.h> #include <string.h> ...