C# LINQ到实体和空字符串
在使用EF4.0作为数据库后端的ASP.NET4.0Web应用程序上发生了一件非常奇怪的事情。本质上,我有一个表存储用户的密码重置请求,其中包含byte[]类型的重置键、DateTime类型的到期日,以及用户的外键(包含字符串电子邮件和字符串名称)。有些用户没有设置电子邮件地址,因此对于PasswordRequest请求,request.email为空 问题出在这里。这非常好: 字符串u=请求[u]; 字符串e=请求[e]; var requests=来自context.PasswordRequests中的r 其中r.User.Name==u&&r.User.Email==null&&r.Expiry>=DateTime.Now 选择r; 我得到的预期结果数为非零,因为存在带有空电子邮件的条目 但当e为null时,它总是返回一个空集合: 字符串u=请求[u]; 字符串e=请求[e]; var requests=来自context.PasswordRequests中的r 其中r.User.Name==u&&r.User.Email==e&&r.Expiry>=DateTime.Now 选择r; 我能正常工作的唯一一件逻辑上没有任何意义的事情是: 字符串u=请求[u]; 字符串e=请求[e]; 可查询的请求; 如果e==null requests=来自context.PasswordRequests中的r 其中r.User.Name==u&&r.User.Email==null&&r.Expiry>=DateTime.Now 选择r; 其他的 requests=来自context.PasswordRequests中的r 其中r.User.Name==u&&r.User.Email==e&&r.Expiry>=DateTime.Now 选择r;C# LINQ到实体和空字符串,c#,asp.net,sql-server,entity-framework,linq-to-entities,C#,Asp.net,Sql Server,Entity Framework,Linq To Entities,在使用EF4.0作为数据库后端的ASP.NET4.0Web应用程序上发生了一件非常奇怪的事情。本质上,我有一个表存储用户的密码重置请求,其中包含byte[]类型的重置键、DateTime类型的到期日,以及用户的外键(包含字符串电子邮件和字符串名称)。有些用户没有设置电子邮件地址,因此对于PasswordRequest请求,request.email为空 问题出在这里。这非常好: 字符串u=请求[u]; 字符串e=请求[e]; var requests=来自context.PasswordRequ
我完全被难住了。有什么想法吗?基本上,在处理空值时,SQL和C之间是不匹配的。您不需要使用两个查询,但需要:
where r.User.Name == u && (r.User.Email == e ||
(e == null && r.User.Email == null))
这很烦人,可能有一个帮助函数让生活更简单,但它基本上来自SQL的空处理
where X = Y
如果X和Y都为空,则不匹配。而在C中,等价的表达式是真的
您可能也需要对u执行相同的操作,除非该操作在数据库中不可为null
如果您对以相同方式处理空字符串和空字符串感到满意,那么至少可以尝试一个小技巧:
// Before the query
e = e ?? "";
// In the query
where r.User.Name == u && (r.User.Email ?? "") == e
我相信这将在email列和e上执行null合并,因此您永远不会将null与任何东西进行比较。我发现了几篇详细介绍相同问题的文章。不幸的是,到目前为止我还没有面对这个问题。不过这很有趣 在这里:
如果您想在请求['e']==null时从数据库检索项目,请从MSDN: 应该是的
var requests = from r in context.PasswordRequests
where r.User.Name == u && r.User.Email is null && r.Expiry >= DateTime.Now
select r;
注意==null和is null是不同的。见->
因此,您的最后一个示例是有效的,因为您需要两种方法从数据库获取数据。i、 e.一个是如果email为null,另一个是如果email==Request['e']如果您喜欢像我一样使用方法lambda语法,您可以这样做:
var result = new TableName();
using(var db = new EFObjectContext)
{
var query = db.TableName;
query = value1 == null
? query.Where(tbl => tbl.entry1 == null)
: query.Where(tbl => tbl.entry1 == value1);
query = value2 == null
? query.Where(tbl => tbl.entry2 == null)
: query.Where(tbl => tbl.entry2 == value2);
result = query
.Select(tbl => tbl)
.FirstOrDefault();
// Inspect the value of the trace variable below to see the sql generated by EF
var trace = ((ObjectQuery<REF_EQUIPMENT>) query).ToTraceString();
}
return result;
实际表中的Email字段是否声明为空列?能否发布生成的sql?啊哈!我想可能会这样,但我不确定到底是什么原因造成的。谢谢你的澄清!干得好!这里的条件有点松。因此,我想为e输入所有三个可能的值是有意义的。我遇到了一个问题,我的数据库中包含一个允许空值的INT列,因此其他一些解决方案对我不起作用大多数解决方案都处理字符串-你的最后一段代码救了我的命!谢谢以下是我最终使用的:w.AccountID_AccountID==\u AccountID这应该被认为是Linq to Entities或Linq to sql中的一个bug——它也发生在那里。这个在Connect上开着吗?我找不到任何东西。好的,找到了,而且在一些更新版本的EF:usiverlinks中似乎已经修复了。谢谢你的发帖!