統合検索機能で使用される次の 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 をメモリに描画するのではなく生成することができます。