【问题标题】:Using a enum with flag in an Entity Framework query在实体框架查询中使用带有标志的枚举
【发布时间】:2021-04-29 05:34:54
【问题描述】:

我有一个像下面这样的枚举类型

  [Flags]
    public enum WeekDays
    {

        Monday = 1,
        Tuesday = 2,
        Wednesday = 4,
        Thursday = 8,
        Friday = 16,
        Saturday = 32,
        Sunday = 64,
    }


   WeekDays dw = WeekDays.Friday | WeekDays.Monday | WeekDays.Saturday;

   int dwInt = (int)dw;

   var list = query.Where(f => f.FromDateTime.DayOfWeek == dwInt "??????????? what can i do there????").ToList();

【问题讨论】:

  • 你知道你什么都没问吗?
  • 我写了???????????我可以在那里做什么????
  • @tobias 不要将您的问题放在代码本身中,尤其是当我们需要滚动才能找到它时。
  • @JonathanSampson,感谢您的建议。

标签: c# .net linq entity-framework entity-framework-4


【解决方案1】:

从 Entity Framework 6.1 开始,您可以在请求中使用 HasFlag 扩展方法。

例如:

query.Where(f => f.FromDateTime.DayOfWeek.HasFlag(WeekDays.Friday | WeekDays.Monday)).ToList();

有关功能请求和实施的详细信息,请参阅https://entityframework.codeplex.com/workitem/1497

【讨论】:

【解决方案2】:

我猜测您不确定要在查询中输入什么来过滤您在源中列出的日期。

鉴于您的源 sn-p,我认为可以安全地推断 dwInt 被用作位掩码,并且 DayOfWeek 将有一个位位置“设置”以指示给定的星期几。在此基础上,您要做的是在 Where is perform a logical bitwise AND on DayOfWeek 字段中使用 dwInt,然后检查结果是否大于 0,这意味着设置了所需的星期几“位”之一你的目标领域。我相信这可以解决问题:

var list = query.Where(f => (f.FromDateTime.DayOfWeek & dwInt) >0).ToList()

如果我对您的问题的解释有误,请见谅。

【讨论】:

  • 请注意,这不适用于实体框架查询,因为它不会转换为 SQL。您必须调用 ToList() 并对生成的内存集合执行 Where()
  • 在没有 .ToList() 的情况下使用 EF 5、.NET 4.5 为我工作
  • (我知道我正在对此进行死灵法,但对于像我这样的随机谷歌用户:)Worked for me using EF 5 - 但是您的查询在服务器上完成了一半,在本地完成了一半(部分 EF 不理解有点操作,在本地完成),这会严重损害性能。 EF Core 不支持这种行为,它会抛出异常,让你知道你必须使用 .ToArray() 并在本地执行 - 所以你可以决定“没关系”或“天哪,那很糟糕,让我们试试吧提出不同的解决方案”。
【解决方案3】:

[HasFlags] 属性在某种意义上非常有趣,除了 .ToString() 和 (AFAIK) Enum.Parse() 操作之外,它不会影响任何东西。因此,对于非字符串操作,您的枚举类型是否具有 [HasFlags] 属性并不重要。枚举在 EF 中的工作方式是它们只是被强制转换为基础类型,并被视为以下整数类型之一 int64、int32、int16、byte、sbyte(注意 EDM 不支持无符号整数类型,因此具有无符号基础类型的枚举将不起作用,并且在数据库中枚举列只是对应于上述类型之一的类型的列)。这意味着基本上任何对整数值(EF 支持的类型)有效的操作对枚举值都有效,除非编译器不允许这样做(我认为我不知道有这样的操作)。 这也意味着无论你想把你的 ????如果它编译应该可以工作(Sql Server 支持按位运算)

【讨论】:

    【解决方案4】:

    解决方案来了

     public static Dictionary<int, int> map = new Dictionary<int, int>() { { 0, 64 }, { 1, 1 }, { 2, 2 }, { 3, 4 }, { 4, 8 }, { 5, 16 }, { 6, 32 } };
    
    //actually,this comes from the user interface, but we should focus on the database layer
    WeekDays[] dw = new WeekDays[] {WeekDays.Saturday,WeekDays.Tuesday,WeekDays.Wednesday };
        
    int[] systemDayOfWeekList = new int[daysOfWeek.Length];
        
    for (int i = 0; i < daysOfWeek.Length; i++)
    {
      systemDayOfWeekList[i] = map.FirstOrDefault(e => e.Value == (int)daysOfWeek[i]).Key;
    }
        
    query = query.Where(f => dayOfWeekList.Contains(((int)SqlFunctions.DatePart("dw", f.FromDateTime))));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多