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,而不是将其绘制到内存中。

Linq复杂搜索导致NullReferenceException

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 }

因为这是左连接的结果