Linq表达式(包含OR)错误地计算WHERE子句?

时间:2014-04-18 11:47:45

标签: c# entity-framework linq-to-entities

我有一个奇怪的情况,我找不到为什么Linq 2实体查询没有返回结果。

第一个查询 返回结果,但第二个不返回结果。

summaryData = db.PromoSummary.Where(x => x.Month == state.OldPromoStart.Month).ToList();
summaryData = db.PromoSummary.Where(x => (x.Month == state.OldPromoStart.Month) | (x.Month == state.OldPromoEndMonthMax)).ToList();

如果" A"是真的,那么" A或B"也应该是真的......(在这种情况下,第一个陈述是真的,所以它应该返回结果而不管第二个陈述,对吗?)

P.S。 db是DbContext,PromoSummary是DbSet

任何想法我做错了什么?

修改

此PromoSummary DbSet包含Month == 9的行,但没有Month == 10的行。到||,但结果是一样的 - 第一个查询返回结果,但第二个查询返回0个记录......

summaryData = db.PromoSummary.Where(x => x.Month == 9).ToList();
summaryData = db.PromoSummary.Where(x => (x.Month == 9) || (x.Month == 10)).ToList();

编辑#2

我想这就是安德鲁建议的......为什么这样做"不是空的"检查? 附:在数据库中,Month属性称为SummaryMonth(使用Fluent api定义)还有一件事 - 此属性的类型为 byte

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[CustomerId] AS [CustomerId], 
[Extent1].[SummaryYear] AS [SummaryYear], 
[Extent1].[SummaryMonth] AS [SummaryMonth], 
[Extent1].[ThemeId] AS [ThemeId], 
[Extent1].[CurrentStateId] AS [CurrentStateId]
FROM [PromotionSummary] AS [Extent1]
WHERE ((9 = ( CAST( [Extent1].[SummaryMonth] AS int))) 
         AND ( CAST( [Extent1].[SummaryMonth] AS int) IS NOT NULL)) 
   OR ((10 = ( CAST( [Extent1].[SummaryMonth] AS int))) 
         AND ( CAST( [Extent1].[SummaryMonth] AS int) IS NOT NULL))

3 个答案:

答案 0 :(得分:3)

您应该使用||代替按位或|

对于第二次更新,请尝试使用以下代码:

List<byte> months = new List<byte> {9, 10};

summaryData = db.PromoSummary.Where(x => months.Contains(x.Month)).ToList();

答案 1 :(得分:2)

您应该使用||运算符代替|

summaryData = db.PromoSummary.Where(x => (x.Month == state.OldPromoStart.Month) || (x.Month == state.OldPromoEndMonthMax)).ToList();

|运算符是二进制OR,但||是逻辑运算符。

答案 2 :(得分:1)

因为你的OR是Binary OR

你应该这样写:

db.PromoSummary.Where(x => (x.Month == state.OldPromoStart.Month) 
       || (x.Month == state.OldPromoEndMonthMax)).ToList();

编辑

考虑到此可能是 SQL驱动程序问题,您可能会尝试执行此类操作。 LINQ以延迟执行而闻名,因此您可以写:

var first =  db.PromoSummary.Where(x => (x.Month == state.OldPromoStart.Month));
var second=  db.PromoSummary.Where(x => (x.Month == state.OldPromoEndMonthMax));

first.AddRange(second);     
return first.FirstOrDefault();

应该生成您正在搜索的SQL,因此也会产生理想的结果。