Linq复杂搜索导致NullReferenceException
本文关键字:NullReferenceException 搜索 复杂 Linq | 更新日期: 2023-09-27 18:13:29
我在统一搜索函数中使用了以下LINQ代码。
var searchObjects =
from objectA in this.context.DB.objectAs
join objectB in this.context.DB.objectBs on objectA equals objectB.objectA into objectAB
from AB in objectAB.Where(o => o.Type == "BasicGroup").DefaultIfEmpty()
select new { objectA, objectB = AB};
foreach (var searchWord in searchWords)
{
var searchObjects =
searchObjects.Where(p => p.objectA.Name.Contains(searchWord) ||
(p.objectB != null &&
(p.objectB.Name.Contains(searchWord) ||
p.objectB.ID.contains(searchWord))));
}
目标是在objectA的Name字段或关联的objectA的Name或ID字段中查找搜索词。问题是,当我试图枚举searchObjects时,它只返回一个NullReferenceException,没有进一步的细节。
查询的第一部分返回组合对象的适当列表(没有任何过滤器),所以我不认为问题是与左连接?
我不知道是什么原因导致了这个异常,所以请帮助我将不胜感激。
我也在使用Telerik的开放访问ORM,但我不认为这应该在这里造成任何问题?
编辑:原来这是一个问题与Telerik OpenAccess ORM,它在某些条件下会放弃产生合理的SQL,绘制到内存中的一切,并将其视为L2Objects(这应该失败的null,由@ dead . rabbit指出)。看起来至少是部分问题的条件是. where (o => . type == "BasicGroup")在. defaultifempty()之前。更新到最新版本的OpenAccess(我认为是2013 Q1 SPI)允许我将该条件重写为equals语句的一部分
on new { objectA.ID, Type = "BasicGroup" } equals new { ID = objectB.AID, Type = object.Type }
这在SP1之前是不可能的。使用这个新查询,我可以将searchword Where子句组合到查询中,并且仍然让它生成SQL,而不是将其绘制到内存中。
AB可以为空,因为您创建它与DefaultIfEmpty()
函数,但也如果ObjectA.Name
可以为空;第二个语句中的Contains()
将抛出错误。类似地,如果ObjectB。ID或ObjectB。当ObjectB不为空时,Name可以为空,那么您的ObjectB != null
保护子句将无法达到预期的效果。
尝试对对象进行简单枚举,以确保问题与您的第一个查询有关
foreach( var item in searchObjects )
Console.WriteLine( item.Type );
每次迭代都重新定义searchObjects变量,我认为这在代码转储中丢失了一些东西,但值得一提的是JIC。
最后,我不确定OpenAccess ORM,因为我从来没有使用过它,但是这个查询会在LINQ的Dynamics CRM实现上失败,它不支持where子句中的某些类型的条件(我不会详细说明,因为它无关紧要,但是你在这个查询中打破了所有这些:p)。对于第三方LINQ实现中的问题,绝对值得浏览一下文档。
我不是100%确定,但我认为你需要在你的匿名类型中使用AB
而不是objectB
。
select new { objectA, AB }
因为这是左连接的结果