2016-11-18 79 views
0

我有使用DefaultIfEmpty方法的實體框架的問題。以下查詢在返回符合數據庫中所有條件的商品時返回空白。實體框架錯誤使用DefaultIfEmpty()

如果我刪除一個或兩個DefaultIfEmpty方法調用它的作品,但與他們不一致。我需要那些預先查詢中的另一個問題。

當我直接在數據庫上執行生成的SQL查詢時,它會工作並返回報價。

我也做了一個單元測試重現相同的例子,它也通過所以它必須是一個實體框架問題。

這裏的查詢:

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

更改它分成兩個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

你說的解決方案有一個問題,因爲我需要查詢來生成兩個'LEFT OUTER JOIN's,如果我這樣做,查詢將生成一個'INNER JOIN'和一個'LEFT OUTER JOIN'。 – Tobi

+0

我試着解釋第一個外連接不會添加任何內容。 –

+0

事情是,我需要兩個都是'LEFT OUTER JOIN',因爲如果第一個過濾器的條件返回null,那麼不管其他過濾器的條件的值如何,查詢也會返回null。 – Tobi