我最近将此代码迁移到实体框架4,它失败了。显然,如果status没有值,则返回所有匹配,如果它有值匹配user.StatusID == 1
.
return users.SingleOrDefault(
user =>
user.Username == username &&
user.EncryptedPassword == password &&
(!status.HasValue || user.StatusID == 1)
);
异常返回:
ArgumentException: The specified value is not an instance of type 'Edm.Int32'
Parameter name: value
然而,删除条件测试,它工作良好:
return users.SingleOrDefault(
user =>
user.Username == username &&
user.EncryptedPassword == password &&
user.StatusID == 1
);
任何想法?如何在EF 4中执行条件测试?肯定不会分开行吧?
我在Linq to Sql中一次又一次地使用这些条件测试;这真的很奇怪,为什么这在EF 4中不起作用。一定是一些简单的地方出了问题,也许在EF 4.0中有一个推荐的替代方法。谢谢大家的帮助,
格雷厄姆
好吧,我用两种方法解决了这个问题。
- 做一个简单的空测试。
- 不使用
.Value
方法测试局部铸态status
变量
两者都必须到位,否则它将继续失败并出现错误!测试value属性会很好,但我猜查询必须非常简单-非常有趣!
return users.SingleOrDefault(
user =>
user.Username == username &&
user.EncryptedPassword == password &&
(status == null || user.StatusID == (int) status)
);
我会等待任何更好的实现,否则接受我自己的答案。但是谢谢大家的帮助。
如何为!status.HasValue
创建单独的变量并在查询中使用此变量?
我认为这里的问题是EF试图将您的状态变量作为参数传递到查询中,然后在SQL本身中执行逻辑。
在where子句中进行空检查的另一种方法是分离出可选参数,只在需要时应用它。
。
var data = users.Where(
user =>
user.Username == username &&
user.EncryptedPassword == password
);
if (status.HasValue)
{
data = data.Where(user => user.StatusID == status.Value);
}
return data.FirstOrDefault();
看起来你已经找到了解决方案…
然而,只是提醒一下……我对VS 2010
中的以下行没有问题 Nullable<int> status = 0;
String username = "Alexandre 2";
var test = _context.Contacts.SingleOrDefault(c => c.FirstName == username && (!status.HasValue || c.ContactID == 1));
我没有得到错误,我期望的Contact对象是返回…所以,如果有的话,这让我想知道你的用户是什么类型的。StatusID字段?
祝你好运
我认为你应该附上user。StatusID == 1在额外的一组括号中,因为我认为目前EF试图将||操作应用于状态。HasValue和user。StatusId,然后与1比较结果
什么是status.HasValue
?如果status是User
的一个字段,你应该这样称呼它:user.status.HasValue
所以只要这样做:
if(status.HasValue)
return users.SingleOrDefault(
user =>
user.Username == username &&
user.EncryptedPassword == password &&
user.StatusID == 1
);
return users.SingleOrDefault(
user =>
user.Username == username &&
user.EncryptedPassword == password
);
乍一看,我的脑海里是这样的:
return users.SingleOrDefault(
user =>
user.Username == username &&
user.EncryptedPassword == password &&
(status == null || user.StatusID == 1)
);
但是当我看得更多的时候,我觉得这是错误的,所以怎么了?
return users.SingleOrDefault(
user =>
user.Username == username &&
user.EncryptedPassword == password &&
status != null &&
user.StatusID == 1)
);
它背后的业务逻辑到底是什么?