Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework LINQ到实体:如何包含条件where条件_Entity Framework_Linq To Entities - Fatal编程技术网

Entity framework LINQ到实体:如何包含条件where条件

Entity framework LINQ到实体:如何包含条件where条件,entity-framework,linq-to-entities,Entity Framework,Linq To Entities,我是EntityFramework新手,在查询中遇到了一个不支持的函数问题。 因此,我希望社区能够帮助找到一种优雅的方式。 查询尝试根据用户名和/或windows用户名查找用户。 [标志] 公共枚举标识符类型 { 用户名=1, Windows=2, Any=用户名|窗口, } 以下代码引发一个NotSupportedException,因为Enum.HasFlag无法转换为存储表达式 public User GetUser(标识符类型,字符串标识符,bool-loadRelations=fal

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

[标志]
公共枚举标识符类型
{
用户名=1,
Windows=2,
Any=用户名|窗口,
}
以下代码引发一个NotSupportedException,因为Enum.HasFlag无法转换为存储表达式

public User GetUser(标识符类型,字符串标识符,bool-loadRelations=false)
{
使用(var context=contextFactory.Invoke())
{
var user=context.Users.FirstOrDefault(u=>u.Username==identifier&&type.HasFlag(IdentifierType.Username)
||u.WindowsUsername==标识符和类型.HasFlag(IdentifierType.Windows));
返回用户;
}
}
如果我以旧方式重写查询,则查询可以工作,但布尔逻辑在数据库中执行:

public User GetUser(标识符类型,字符串标识符,bool-loadRelations=false)
{
使用(var context=contextFactory.Invoke())
{
var user=context.Users.FirstOrDefault(u=>u.Username==identifier&&(type&IdentifierType.Username)==IdentifierType.Username
||u.WindowsUsername==标识符&&(type&IdentifierType.Windows)==IdentifierType.Windows);
返回用户;
}
}
其中((Username=@Username)和(1=(3&(1)))或(WindowsUsername) =@windowsusername)和(2=(3&(2)))

如何强制框架在将布尔逻辑发送到DB之前对其求值,从而使二进制操作不在DB级别执行?

任何想法都非常感谢

例如:

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))是一个常数,这就是(我已经将我的代码转换成了你的代码,所以可能不是100%)了


对不起,我意识到问题没有指出有效的问题。在读了更多关于这方面的内容后,我不得不重写这个问题,最终从格特·阿诺德那里得到了一个很好的答案,见


提供了功能强大的扩展,如PredicateBuilder,以覆盖带有或条件的动态查询。

Hi。这仍然对数据库执行二进制操作。我认为一定有办法让实体框架只将WHERE条件发送到由标志启用的DB。例如,如果(1&2)=1,则不会将WHERE Username=@identifier条件添加到查询中。@ThomasZweifel在我的示例中,您将得到1=1,而不是(1&2)=1。我认为你的要求没有得到落实。我想象的唯一方式是使用3+1案例进行“开关式”编码。但我认为db服务器将进行优化,就像.net在执行时所做的那样。@ThomasZweifel通过反转&&子句来尝试:而不是a&&b | | c&&d,尝试b&&a | | d&&c来查看.net是否被“使用”。
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;
    }
}