【问题标题】:Enum.HasFlag in LINQ to Entities?LINQ to Entities 中的 Enum.HasFlag?
【发布时间】:2012-09-06 19:15:27
【问题描述】:

我有一个标志,例如

[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)' 方法,并且该方法无法转换为存储表达式。

【问题讨论】:

标签: c# linq c#-4.0 lambda linq-to-entities


【解决方案1】:

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

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。

【讨论】:

  • 我不明白完全你所说的二进制操作是什么意思。我知道它会将数字降低到字节并根据数字比较位,但对于我需要如何更新我的 lambda,我无法做出精神上的飞跃。我将如何更新我的 lambda 以使 weekends 工作?
  • 当然。我编辑了我的答案。因为您使用的是 EF,所以您不能在函数中抽象操作,因为这不会转换为 SQL。
  • @Shimmy 我不知道。对其进行测试并在 EF 项目上打开一个 GitHub 问题。他们需要一些东西来跟踪这个功能请求。
【解决方案2】:

Looks like 已在 EF 6.1 中修复。

但是,关于 EF Core,请查看 this

【讨论】:

    【解决方案3】:

    解决方案结合了@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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-29
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多