4

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

[Flags]
public enum Status
{
  None = 0,
  Active = 1,
  Inactive = 2,
  Unknown = 4
}

状态枚举可能包含两个值,例如:

Status s = Status.Active | Status.Unknown;

现在我需要创建一个 linq 查询(LINQ to ADO.NET Entities)并询问状态为 s 以上的记录,即 Active 或 Unknown;

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

当然我得到一个错误,因为 LINQ to Entities 只知道在 Where 子句中处理原始类型。

错误是:

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

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

谢谢。

更新

这似乎是一个 Linq to Entity 问题。我认为在 LINQ to SQL 中它可以工作(不确定,没有测试)。

4

7 回答 7

8

只需使用HasFlag()

var result = from r in db.Records
         where r.Status.HasFlag(s)
         select r
于 2014-12-31T17:38:17.757 回答
2

在 DB Flags 中,枚举必须是整数。之后,您可以像这样尝试:

Status s = Status.Active | Status.Unknown;

var result = from r in db.Records
where (s & r.Status) == r.Status
select r
于 2015-10-23T12:34:46.407 回答
1
var result = from r in db.Records
             where r.Status == s
             select r
于 2009-09-15T11:38:51.400 回答
0

我不知道 EF,但可以插入额外的演员表吗?

var result = from r in db.Records
             where ((byte)r.Status & (byte)s) == (byte)r.Status
             select r
于 2009-09-15T11:32:22.353 回答
0

试试这样:

byte status = (byte)(Status.Active | Status.Unknown);

var result = from r in db.Records
             select r
             where (r.Status & status) != 0
于 2009-09-15T11:35:06.827 回答
0

我不确定按位与运算是否可行,但请尝试将 s 转换为 int:

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

您使用的是哪个数据库引擎?可能引擎不支持按位运算。

参考: http: //www.matthidinger.com/archive/2008/02/26/entity-framework-comparison-frustration-explained.aspx

于 2009-09-15T12:09:10.777 回答
0

以下内容在 C# 中对我有用

    public const StatusTypes ActiveAlert = StatusTypes.Accepted | StatusTypes.Delivered;

        int flags = (int)ActiveAlert;

        try
        {
            var query = from p in model.AlertsHistory
                        where (p.UserId == clientId
                        && (p.Status.HasValue && (p.Status.Value & flags) != 0))
                        select p;
            var aList = query.ToList();

            return (aList);


        }
        catch (Exception exc)
        {
            log.Error("Exception getting Alerts History for user.", exc);
            throw;
        }
于 2009-09-17T18:43:15.567 回答