多个按位标志组合

时间:2013-07-31 12:17:43

标签: c# .net entity-framework entity-framework-5 flags

我有一个方法,它显示项目的枚举标志参数。数据库中的项可以设置多个标志,传递给该方法的值也可以设置多个标志。 例如:

Item1 = Flag1
Item2 = Flag1 | Flag3
Item3 = Flag2 | Flag3

我希望能够将这些值传递给方法并返回相应的项目。

  • 如果我通过Flag2 | Flag3,返回Item2和Item3(因为每个标志与实体中设置的标志之一匹配)
  • 如果我通过Flag1,则返回Item1和Item2

...等。我一直在试验.Where和.Any,我仍然完全不知道怎么做,如果它甚至可能。我的目标是使用.NET 4.5并使用EF5。

4 个答案:

答案 0 :(得分:2)

使用按位And运算符

MyFlags value = MyFlags.Flag2 | MyFlags.Flag3;

MyFlags item1 = MyFlags.Flag1;
MyFlags item2 = MyFlags.Flag1 | MyFlags.Flag3;
MyFlags item3 = MyFlags.Flag2 | MyFlags.Flag3;

bool matchItem1 = (value & item1) > 0; //false
bool matchItem2 = (value & item2) > 0; //true
bool matchItem3 = (value & item3) > 0; //true

[Flags]
enum MyFlags
{
    Flag1 = 1,
    Flag2 = 2,
    Flag3 = 4
}

答案 1 :(得分:1)

给出一个MyItems列表,每个MyItems都有一个MyFlags类型的Flags属性:

public IEnumerable<MyItem> GetItemsWithFlag(IList<MyItem> items, MyFlags flags) {
    var flagsL = Convert.ToUInt64(flags);

    foreach (var value in Enum.GetValues(typeof(MyFlags))) {
        var valueL = Convert.ToUInt64(value);

        if ((flagsL & valueL) == valueL) {
            foreach (var item in items) {
                var itemL = Convert.ToUInt64(item.Flags);

                if ((itemL & valueL) == valueL) {
                    yield return item;
                }
            }
        }
    }
}

这将循环遍历所有可能的标志,如果在参数flags中设置了标志,则返回在Flags属性中设置该标志的所有项目

答案 2 :(得分:0)

我相信这是可能的。你的枚举必须设置[Flags]属性,然后就像.Where那样简单(p =&gt; p.Flags == FilterFlags)

R ead more about Enum flags here

答案 3 :(得分:0)

我看错了方法。对我来说,旗帜更像是FlagsToExclude。例如:

[Flags]
public enum ForumTopicFlags : int
{
    None = 0,
    Sticky = 1,
    Spam = 2,
    Deleted = 4
}

默认标志为0。对于版主,我需要传递null作为参数,DAL会忽略该参数并返回eveything。对于标准用户,我可以传递Spam | Deleted,通过比较它来排除{<1}}:

var filteredFlags = dbContext.Topics.Where(i => (i.Flags & flagsToExclude <= 0);