LINQ to Entity:如何包含条件where条件

时间:2013-01-30 13:22:25

标签: entity-framework linq-to-entities

我是EntityFramework的新手,遇到了查询中使用的不受支持的函数的问题。 因此,我希望社区可以帮助找到一种优雅的方式 查询尝试根据用户名和/或Windows用户名查找用户。

[Flags]
public enum IdentifierType
{
    Username = 1,
    Windows = 2,
    Any = Username | Windows,
}

以下代码抛出 NotSupportedException ,因为Enum.HasFlag无法转换为商店表达式。

public User GetUser(IdentifierType type, string identifier, bool loadRelations = false)
{
    using (var context = contextFactory.Invoke())
    {
        var user = context.Users.FirstOrDefault(u => u.Username == identifier && type.HasFlag(IdentifierType.Username)
        || u.WindowsUsername == identifier && type.HasFlag(IdentifierType.Windows));

        return user;
    }
}

如果我用旧的Fashion方式重写查询,Query会工作,但布尔逻辑在DB中执行:

public User GetUser(IdentifierType type, string identifier, bool loadRelations = false)
{
    using (var context = contextFactory.Invoke())
    {
        var user = context.Users.FirstOrDefault(u => u.Username == identifier && (type & IdentifierType.Username) == IdentifierType.Username
        || u.WindowsUsername == identifier && (type & IdentifierType.Windows) == IdentifierType.Windows);

        return user;
    }
}
  

WHERE((Username = @username)AND(1 =(3&(1))))OR(WindowsUsername   = @windowsusername)AND(2 =(3&(2))))

如何在将布尔逻辑发送到数据库之前强制框架评估布尔逻辑,因此二进制操作不是在数据库级别完成的?

任何想法都非常感激!

3 个答案:

答案 0 :(得分:0)

例如:

public User GetUser(IdentifierType type, string identifier, bool loadRelations = false)
{
    using (var context = contextFactory.Invoke())
    {
        IdentifierType tw = type & IdentifierType.Windows;
        IdentifierType tu = type & IdentifierType.Username;
        var user = context.Users.FirstOrDefault(u => u.Username == identifier && tu == IdentifierType.Username
        || u.WindowsUsername == identifier && tw == IdentifierType.Windows);

        return user;
    }
}

但我希望并相信数据库服务器检测到1 =(3&(1))是一个常数

答案 1 :(得分:0)

在这里(我已将我的代码转换为您的代码,因此可能在语法上不是100%)...

public User GetUser(IdentifierType type, string identifier, bool loadRelations = false)
{
    using (var context = contextFactory.Invoke())
    {
        var user = context.Users.FirstOrDefault(u => u.Username == ((type.HasFlag(IdentifierType.Username)) ? identifier : u.Username) && 
    && u.WindowsUsername == ((type.HasFlag(IdentifierType.Username)) ? identifier : u.WindowsUsername);

        return user;
    }
}

答案 2 :(得分:0)

对不起,我意识到这个问题没有指出有效问题。在阅读了更多相关内容之后,我不得不重写这个问题,最后得到了Gert Arnold的一个很好的答案,见here

LINQKit提供强大的扩展功能,例如 PredicateBuilder ,以涵盖OR条件下的动态查询。