Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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
.net 如何在Linq to Entities查询中使用标志枚举?_.net_Linq_Enums_Flags - Fatal编程技术网

.net 如何在Linq to Entities查询中使用标志枚举?

.net 如何在Linq to Entities查询中使用标志枚举?,.net,linq,enums,flags,.net,Linq,Enums,Flags,我有这样一个[Flags]枚举: [Flags] public enum Status { None = 0, Active = 1, Inactive = 2, Unknown = 4 } byte status = (byte)(Status.Active | Status.Unknown); var result = from r in db.Records select r where (r.Status &

我有这样一个[Flags]枚举:

[Flags]
public enum Status
{
  None = 0,
  Active = 1,
  Inactive = 2,
  Unknown = 4
}
byte status = (byte)(Status.Active | Status.Unknown);

var result = from r in db.Records
             select r
             where (r.Status & status) != 0
Status s = Status.Active | Status.Unknown;

var result = from r in db.Records
where (s & r.Status) == r.Status
select r
状态枚举可以包含两个值,例如:

Status s = Status.Active | Status.Unknown;
现在我需要创建一个linq查询(linq到ADO.NET实体)并请求状态为s以上的记录,即活动或未知的记录

var result = from r in db.Records
             select r
             where (r.Status & (byte)s) == r.Status
当然,我会得到一个错误,因为LINQtoEntities只知道在Where子句中处理基元类型

错误是:

无法创建的常量值 类型“闭包类型”。只有原始的 类型('如Int32、String和 在此上下文中支持Guid')

有可行的方法吗?我可能有一个包含10个可能值的状态枚举,并查询其中5个状态。如何以优雅的方式使用Flags enum构造查询

谢谢

更新


这似乎是一个Linq到实体的问题。我认为在LINQtoSQL中它可以工作(不确定,没有测试过)。

我不知道EF,但是插入额外的强制转换可以工作吗

var result = from r in db.Records
             where ((byte)r.Status & (byte)s) == (byte)r.Status
             select r
试着这样做:

[Flags]
public enum Status
{
  None = 0,
  Active = 1,
  Inactive = 2,
  Unknown = 4
}
byte status = (byte)(Status.Active | Status.Unknown);

var result = from r in db.Records
             select r
             where (r.Status & status) != 0
Status s = Status.Active | Status.Unknown;

var result = from r in db.Records
where (s & r.Status) == r.Status
select r

我不确定按位AND运算是否有效,但请尝试将s强制转换为int:

        int i = (int)s;
        var result = from r in db.Records
             select r
             where (r.Status & i) == r.Status
您正在使用哪个数据库引擎?引擎可能不支持按位操作


参考资料:

以下内容适用于我的C语言#


看看下面的好帖子,它向您展示了以下备选方案:

  • 已设置至少一个选定标志
  • 设置了完全相同的标志
  • 至少包括您选择的那些标志以及更多

只需使用
hassflag()


数据库中的标志枚举必须为整数。之后,您可以这样尝试:

[Flags]
public enum Status
{
  None = 0,
  Active = 1,
  Inactive = 2,
  Unknown = 4
}
byte status = (byte)(Status.Active | Status.Unknown);

var result = from r in db.Records
             select r
             where (r.Status & status) != 0
Status s = Status.Active | Status.Unknown;

var result = from r in db.Records
where (s & r.Status) == r.Status
select r

r、 状态已经是字节了,我还添加了问题中的强制转换。这不是问题,问题是它不会运行。它编译但不运行。查看问题中的错误。您的查询(如果有效)将只返回状态同时为
活动
未知
的记录。这就是你想要的吗?不,这是一个或不是一个和。所以'Status s=Status.Active | Status.Unknown;'这是正确的。谢谢@Vasi:这部分是正确的,但是“
Status.Active | Status.Unknown
”相当于“
1 | 4
”,即
5
。因此,你的
where
子句实际上是在说“
where(r.Status&5)==r.Status
”,这与“
where r.Status==5
”,这与(英语中)“where
r.Status
既是
活动的
又是
未知的
”是一样的!可以将实体转换为可枚举项。请参阅:从EF6.1开始,LINQ to实体支持HASSFLAG。请看:我认为Where中的评估不可翻译为esql或类似的东西。这就是我遇到异常的原因:“无法创建“Closure type”类型的常量值。在此上下文中仅支持基元类型(“如Int32、String和Guid”)。“通过MS SQL Server将LINQ用于实体。否,这是一个无法将枚举结果转换为本机SQL类型的问题。”。因此,使用整数比较可能有效。我认为它无法将位比较转换为eSql。在发布这个问题之前,我在代码中使用了cast-to-byte,但是当我在这里编写这个简短的示例时,我错过了它。所以这不是强制转换问题,我认为这是一个比较问题,不受EF支持。状态列的数据类型是什么?尽管如此,请尝试强制转换到
int
。这实际上是为EF LINQ->SQL转换器缺陷找到一个解决方法的全部内容。。。你得试试角落里的箱子。