我有一个标志,例如
[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)'方法,并且此方法无法转换为商店表达式。
答案 0 :(得分:20)
枚举标志基于二进制操作。
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。
答案 1 :(得分:2)
Looks like已修复EF 6.1。
关于EF Core,请检查this。
答案 2 :(得分:0)
解决方案是@ usr的答案和对我正在使用的EntityFramework版本的理解的组合。 EF4不支持保存枚举,所以实体保存了一个int?并且对象上枚举的属性未映射到EF。枚举的属性将映射到成员的get / set。
e.g。
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);