如何在Linq to Entities查询中使用标记枚举?

时间:2009-09-15 11:21:26

标签: .net linq enums flags

我有这样的[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 Entities问题。我认为在LINQ to SQL中它可以工作(不确定,没有经过测试)。

8 个答案:

答案 0 :(得分:6)

只需使用HasFlag()

即可
var result = from r in db.Records
         where r.Status.HasFlag(s)
         select r

答案 1 :(得分:2)

看看以下好帖子,它会显示以下备选方案:

  • 至少有一个选定的标志设置
  • 完全相同的标志设置
  • 至少您选择的那些标志和更多

https://timdams.wordpress.com/2011/02/14/using-enum-flags-to-write-filters-in-linq/#comment-30

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

试试这样:

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

var result = from r in db.Records
             select r
             where (r.Status & status) != 0

答案 5 :(得分:0)

我不确定按位AND操作是否有效,但尝试将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

答案 6 :(得分: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;
        }

答案 7 :(得分:0)

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

Status s = Status.Active | Status.Unknown;

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