我在统一搜索功能中使用了以下 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 字段或相关 objectB 的 Name 或 ID 字段中查找搜索词。问题是,当我尝试枚举 searchObjects 时,它只返回 NullReferenceException,没有更多详细信息。
查询的第一部分返回组合对象的正确列表(没有任何过滤器),所以我认为问题不在于左连接?
我无法弄清楚是什么导致了异常,所以任何帮助将不胜感激。
我也在使用 Telerik 的 OpenAccess ORM,但我认为这不会造成任何问题吗?
编辑:
原来这是 Telerik OpenAccess ORM 的一个问题,在某些情况下,它只会放弃生成合理的 SQL,将所有内容都绘制到内存中并将其视为 L2Objects(如@Dead.Rabit 所指出的那样,它应该在 null 上失败) . 似乎至少部分问题的条件是 .DefaultIfEmpty() 前面的 .Where(o => o.Type == "BasicGroup")。更新到最新版本的 OpenAccess(我认为是 2013 Q1 SPI)允许我重写该条件作为 equals 语句的一部分
on new { objectA.ID, Type = "BasicGroup" } equals new { ID = objectB.AID, Type = object.Type }
这在 SP1 之前是不可能的。使用这个新查询,我可以将搜索词 Where 子句组合到查询中,并且仍然让它生成 SQL,而不是将其绘制到内存中。