实体框架中的简单条件LINQ查询



我最近将此代码迁移到实体框架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中有一个推荐的替代方法。

谢谢大家的帮助,
格雷厄姆

好吧,我用两种方法解决了这个问题。

  1. 做一个简单的空测试。
  2. 不使用 .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)
  );

它背后的业务逻辑到底是什么?

相关内容

  • 没有找到相关文章

最新更新