2016-11-18 101 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