繁体   English   中英

LINQ to Entities中的Enum.HasFlag?

[英]Enum.HasFlag in LINQ to Entities?

我有一面旗帜,例如

[Flags]
public enum DaysOfTheWeek
{
    Monday = 1,
    Tuesday = 2,
    Wednesday = 4,
    Thursday = 8,
    Friday = 16,
    Saturday = 32,
    Sunday = 64
}

如果我想使用Linq基于包含特定标志的变量进行过滤,我可以尝试在lambda语句中使用Enum.HasFlag来过滤多个标志,例如

DaysOfWeek weekendFilter = DaysOfTheWeek.Saturday | DaysOfTheWeek.Sunday;
var weekends = allDays.Where(d => d.DayOfWeek.HasFlag(weekendFilter));

这目前给出:

LINQ to Entities无法识别方法'Boolean HasFlag(System.Enum)'方法,并且此方法无法转换为存储表达式。

枚举标志基于二进制操作。

HasFlag = (allDays & (DaysOfTheWeek.Saturday | DaysOfTheWeek.Sunday)) != 0;

如果您愿意,可以将其抽象为扩展方法。

具体地回答你的问题:

DaysOfWeek weekendFilter = DaysOfTheWeek.Saturday | DaysOfTheWeek.Sunday;
var weekends = allDays.Where(d => (d.DayOfWeek & weekendFilter) != 0);

我知道你可以在LINQ to SQL中使用这个谓词。 它将被翻译为SQL(SQL Server支持二进制算术就好了)。 不确定EF是否同样有能力,因为它的LINQ支持通常远远低于L2S。

看起来它已在EF 6.1中修复。

但是关于EF Core,请检查一下

该解决方案结合了@ usr的答案,以及对我正在使用的EntityFramework版本的理解。 EF4不支持保存枚举,所以实体保存了一个int? 并且对象上枚举的属性未映射到EF。 枚举的属性将映射到成员的get / set。

例如

public int? DayOfWeekValue { get; set; }
[NotMapped]
public DaysOfWeek DayOfWeek
{
    get { return (DaysOfWeek)DayOfWeekValue; }
    set { DayOfWeekValue= (int)value; }
}

因为,根据@ usr的回答,过滤器需要使用二进制操作。 这可以通过将标志设置为扩展字节来完成

[Flags]
public enum DaysOfTheWeek : byte
{
    Monday = 1,
    Tuesday = 2,
    Wednesday = 4,
    Thursday = 8,
    Friday = 16,
    Saturday = 32,
    Sunday = 64
}

然后将值和过滤器作为字节进行转换以执行二进制操作:

var weekends = allDays.Where(d => (((byte)d.DayOfWeekValue.Value) & (byte)weekendFilter) != 0);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM