LINQ:在where子句中使用可空值类型

3

我正在尝试查询一个可能包含NULL值的表。根据这个问题,使用object.Equals是解决方法:

DateTime? myDate = null;
var q =
    from row in db.Activities
    where object.Equals(row.FirstActivityTime, myDate)
    select row;

这是可以实现的,但当我给myDate赋一个非空值时,
DateTime? myDate = DateTime.Now;

当所有东西崩溃并抛出异常时,可能会出现以下错误提示:"无法将类型 'System.Nullable`1' 强制转换为类型 'System.Object'。LINQ to Entities 仅支持强制转换 EDM 基元或枚举类型。"

我可以将 where 子句重写为

where row.FirstActivityTime == myDate || (row.FirstActivityTime == null && myDate == null)

但是有没有办法使用 object.Equals 让它起作用呢?

2个回答

3
由于您使用的是LINQ to Entities而不是LINQ to SQL,所以您所引用的问题并不适用。您可以在筛选器中使用row.FirstActivityTime == myDate,EF将生成正确的SQL查询,包括is null检查和等式检查。
编辑
事实证明,这种行为已经有了一些改变,您需要在上下文中设置一个标志以恢复旧的行为。(来源:http://entityframework.codeplex.com/workitem/178)
var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
objectContext.ContextOptions.UseCSharpNullComparisonBehavior = true;

完成此操作后,生成的SQL将包含is null检查。

不行。我已经尝试过了,生成的 SQL 在这种情况下没有所需的“IS NULL”检查。 - John Reynolds
@JohnReynolds,row.FirstActivityTime 是否可空? - Steve Ruble
@JohnReynolds那么使用这个查询时输出有哪些不正确的地方呢? - Servy
@Servy: 如果row.FirstActivityTime和myDate都为NULL,我希望该行被包含在结果集中。但使用此查询时它不会被包含。 - John Reynolds

-5
你应该写成这样:
var q = from row in db.Activities 
        where (mydate.HasValue && 
            DateTime.Equals(row.FirstActivityTime, myDate.Value))
        select row;

-1:这个where子句不会包括任何具有NULL值的行。 - John Reynolds
好的,我明白了。你应该将你的数据库中的FirstActivityTime标记为可为空,并更新你的.edmx文件。否则你将无法执行这样的查询。 - Franck Ngako
@FranckNgako 根据问题中显示的代码,它已经是可空的。 - Servy
@Frank:我能够执行这样的查询。这就是我在原帖中重写的where子句所做的。问题是关于...啊好吧,再读一遍你就会明白了。 - John Reynolds
@Servy 你是对的。那么我的最后一个想法是使用以下语法:Nullable<Datetime>(row.FirstActivityTime, myDate) - Franck Ngako

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接