2016-11-18 21 views
0

DefaultIfEmptyメソッドを使用してEntity Frameworkに問題があります。次のクエリは、データベース内のすべての条件に一致するオファーを返す必要がある場合に空を返します。DefaultIfEmpty()を使用したEntity Frameworkエラー

DefaultIfEmptyメソッド呼び出しのいずれかまたは両方を削除すると機能するが動作しない。私はそれらの質問に別の問題を予感させる必要があります。

生成されたSQLクエリをデータベース上で直接実行すると、それは機能し、オファーを返します。

また、同じサンプルを再現した単体テストを作成し、それも渡してEntity Frameworkの問題でなければなりません。

はここにクエリです:

private static Expression<Func<Offer, bool>> AddFilter(Service criteria) 
{ 
     return offer => offer.Restrictions. 

     SelectMany(rest => rest.OperatorRange.DefaultIfEmpty(), (rest, alop) => new { Restriction = rest, OperatorRange = alop.Id }). 
     Where(alop => criteria.ServiceUseNet == null || alop.OperatorRange.ToUpper() == criteria.ServiceUseNet.ToUpper()). 

     SelectMany(rest => rest.Restriction.CallType.DefaultIfEmpty(), (rest, till) => new { Restriction = rest, CallType = till.Id }). 
     Any(till => criteria.UseServiceCoverage == null || till.CallType.ToUpper() == criteria.UseServiceCoverage.ToUpper()); 
} 

答えて

0

2つのAny呼び出しに変更し、それを:

return offer => offer.Restrictions 
    .Any(rest 
     => rest.OperatorRange 
       .Where(alop => criteria.ServiceUseNet == null 
          || alop.OperatorRange.ToUpper() == criteria.ServiceUseNet.ToUpper()) 
     .Any(till => criteria.UseServiceCoverage == null 
        || till.CallType.ToUpper() == criteria.UseServiceCoverage.ToUpper())); 

は述語がを持つ任意のOperatorRange S(いくつかの基準を満たす)があるかどうかをテストすることになっています任意の基準を満たすCallTypeです。 OperatorRangeがない場合、CallTypeと一致するものの、CallTypeのいずれも存在しません。

この形式では、述語は常にtrueまたはfalseを返します。

+0

2つのLEFT OUTER JOINを生成するためにクエリが必要なので、あなたが言っている解決策に問題があります。そうすれば、クエリは 'INNER JOIN'と' LEFT OUTER JOIN'を生成します。 – Tobi

+0

最初の外部結合が何も追加しないことを説明しようとしました。 –

+0

最初のフィルタの条件がnullを返した場合、他のフィルタの条件の値に関係なく、クエリはnullも返すので、両方とも「LEFT OUTER JOIN」である必要があります。 – Tobi

関連する問題