一例由于用redis缓存一张表到内存导致列表页面在搜索查询的时候出现未将对象引用设置到对象的实例问题的解决

原创 2017年06月28日 10:03:53

通过定位发现出错行在这里:

model = query.ToPagedList(pageIndex, pageSize);

然后在错误堆栈中再找,发现是ToPagedList调用了 System.Linq.Queryable.Count[TSource](IQueryable`1 source)  这个Count方法导致的问题。

为了确定是否是调用这个方法的问题,在model = query.ToPagedList(pageIndex, pageSize); 增加了一行:int a = query.Count(); 编译运行,这次错误定位到这一行。由于我在内存中存储的表是以Redis的 List<T> 形式存储的。因为要分页,并搜索,用到了按多行排序,并且用到了linq的where方法。在处理的时候把List<T> 变为了 IQueryable形式。代码是这样写的:

 var query = RedisQuestionsLibraryList.AsQueryable().Where(lambda);

刚开始以为是redis存储后的数据,经过AsQueryable()改变后再用where 进行lambda查询,C#支持不够好造成。然后根据这种情况在baidu, google及 stackoverflow网站搜索解决方案,均没有结果。后来由于想到另一个页面也使用过这种redis数据进行查询列表,哪个页面却没报错。于是做了比较。哪个页面的查询列表代码如下:

var query = RedisQuestionsLibraryList.AsQueryable().Where(lambda).OrderBy("iid", true);

然后我为了检测,在这行下面增加:

int a = query.Count();

不报错。至此确认并不是 list 泛型使用 AsQueryable() 转换为 IQueryable 对象早成的问题。仔细的比较了这两个页面的查询语句,并且为了严格一样,把出错页面的orderby方法改为和正确页面的一样。执行仍然是错误的页面还报同样的错误。仔细比对这两行代码,也就lambda表达式不同了。没报错的页面lambda表达式只有一个条件查询。而错误页面实多个条件的复合查询。因为确定是查询条件造成的这个问题。我对各个条件分别进行测试。发觉进行其他条件查询都不报错。就用contains方法的这个条件报错。报错语句是这样写的:

lambda = lambda.And(m => m.Title.Contains(search) || m.Option1.Contains(search) || m.Option2.Contains(search) || m.Option3.Contains(search) || m.Option4.Contains(search));

由于报的是未将对象引用设置到对象的实例的错误。首先是怀疑 m.Title ,m.Option1这里值是null造成。因为 String.Contains方法中。前面的string部分是不能为空的。我在数据库中对此表的数据进行了查询,发现Option1 ,Option2等字段中存的值有的时候是为null。于是,对此语句进行改造,改造后的语句如下:

lambda = lambda.And(m => m.Title.Contains(search) || (m.Option1 != null && m.Option1.Contains(search)) || (m.Option2 != null && m.Option2.Contains(search)) || (m.Option3 != null && m.Option3.Contains(search)) || (m.Option4 != null && m.Option4.Contains(search)));

这次编译运行,没这个问题了。显然是这里的问题。可是问题又来了,为什么同样的查询语句,我原来在没有使用 redis 缓存的情况下。从数据库中查询执行,没发生过这样的错误啊。原来从数据库中查询的语句是这样的;

var query = new QuestionsLibraryService().GetNolock(lambda);
怀疑与生成的sql语句有关。于是决定用 sql server profiler对执行的查询语句进行分析。

首先建立一个跟踪。然后清空跟踪窗口中的所有数据。先执行从 redis 缓存中取数据进行查询。在跟踪窗口中查询这个表,毫无疑问,在sql server分析器中没有有关这个表的查询语句。这很好理解,因为用的是 redis 中的缓存表,是在内存中的。自然在 sql server 分析器中不会查询这张表。 然后注释掉自 redis 中获取数据语句,改为自数据库中直接获取数据语句:

//var query = RedisQuestionsLibraryList.AsQueryable().Where(lambda);
 var query = new QuestionsLibraryService().GetNolock(lambda);
编译,执行,这次 sql server profiler中有相关语句了。把此语句复制到 sql server的查询窗口,发现使用 Contains方法的地方,在sql查询语句中被转换为了 like 查询。对这样的like语句进行简化,使用了一条 Option1 字段中包括 null 数据的行进行 like 查询。

SELECT * FROM dbo.Questions WHERE GID='5c3d4eaa-efef-4683-91d5-a771823dfe77' AND Option1 LIKE '%某日%'
在sql 查询窗口执行此语句,正常执行,不会报错。至此明白了为什么在内存中存储的null值进行相应查询的时候会报错,而数据库中的null值为什么不报错。是因为在内存中执行的是真正的string.Contains方法,此方法要求 string 必须不为 null 。而对 数据库进行查询的语句,它经过转换,把 contains 方法转换为了 like sql 查询方法。而 like sql 查询方法中 字段是允许为null的。


版权声明:本文为博主原创文章,未经博主允许不得转载。

加载设计器错误——未将对象引用设置到对象的实例 之解决方法

 这两天在修改一个同事做的UserControl,当我在Load事件中加入如下代码:  private void UCIdcBaseInfo_Load(object sender, EventArgs...
  • dekko
  • dekko
  • 2007年07月04日 13:02
  • 2724

菜鸟和老鸟都无法避免的问题——未将对象引用设置到对象的实例

“未将对象引用设置到对象的实例”相信这个问题只要是写过代码的不论技术高低都会遇到过,这句话的意思就是说我们在引用对象之前没有对对象进行初始化。...
  • u010926964
  • u010926964
  • 2014年12月06日 09:05
  • 4913

VS2017错误:未将对象引用设置到对象的实例

装完python模块之后运行程序就出现这个错误。网上搜了一堆方法都是改注册表。 知乎上有个解决方法:打开--C:\Users\用户名\AppData\Local\Microsoft\VisualSt...
  • lsaejn
  • lsaejn
  • 2017年11月10日 14:50
  • 518

光脚丫学LINQ(040):引发未将对象引用设置到对象的实例的异常

演示视频:http://u.115.com/file/f2737fb613演示重点此演示重点介绍当通过外键导航的方式获取关联数据对象的时候,如果没有找到相关的数据记录,是否就会引发未将对象引用设置到对...
  • gjysk
  • gjysk
  • 2010年12月01日 22:37
  • 1829

未将对象引用设置到对象的实例--连接数据库时

     连接数据库时发生未将对象引用设置到对象的实例的一种情况:现象:我的程序准备用配置文件对连接字符串进行初始化是,编译器抛出异常错误--未将对象引用设置到对象的实例。原因:在下面的程序中,第一句...
  • xwdpepsi
  • xwdpepsi
  • 2011年03月03日 20:19
  • 4501

asp.net经典问题之“未将对象引用设置到对象的实例”

相信几乎所有学过asp.net的朋友都遇到过这个问题:未将对象引用设置到对象的实例。这个问题在我刚开始学习这方面的知识的时候真有点让崩溃的感觉,当时都快打击死我了,不过经过了以后,反而有一种明朗的小激...
  • sunqing0316
  • sunqing0316
  • 2014年03月12日 17:03
  • 59567

未将对象引用设置到对象的实例--可能出现的问题总结

一、网络上的一般说法1、ViewState 对象为Null。2、DateSet 空。3、sql语句或Datebase的原因导致DataReader空。4、声明字符串变量时未赋空值就应用变量。5、未用n...
  • sollion
  • sollion
  • 2010年07月30日 20:07
  • 303165

NPOI导入数据时报错“未将对象引用设置到对象的实例”,解决方案

传值得时候,导入的数据里有为空的单元格,然后前面没有加判断什么的,所以后面会报错。 解决方案就是判断咯~(ExcelMapper里面加个int变量IsNUll,以及构造,默认为0;然后创建的时候必填...
  • qq_31083285
  • qq_31083285
  • 2016年01月04日 16:12
  • 1308

单元测试失败,显示未将对象引用到实例的解决方法

引用到实例    欲用NUnit实行ASP.NET内BLL层的单元测试,却不能正常读取存储在web.config中的ConnectionString信息,参考MSDN找到一个解决方案。      1....
  • xh491464429
  • xh491464429
  • 2010年07月22日 21:56
  • 2029

在发布网站后,出现“未将对象引用设置到对象的实例”的错误时,是什么原因?

这个有两个原因:一、在IIS中没有设置“默认文档”;二、session没有赋值。 这两个原因是在做项目时发现的,可能还有其它的。...
  • ljxqsqmoliwei
  • ljxqsqmoliwei
  • 2012年12月10日 17:16
  • 1807
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一例由于用redis缓存一张表到内存导致列表页面在搜索查询的时候出现未将对象引用设置到对象的实例问题的解决
举报原因:
原因补充:

(最多只允许输入30个字)