Using a enum with flag in an Entity Framework query

15,665

Solution 1

solution is here

 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))));

Solution 2

Starting from Entity Framework 6.1, you can use the HasFlag extension method in your requests.

For example:

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

See https://entityframework.codeplex.com/workitem/1497 for details about the feature request and implementation.

Solution 3

I'm going to make a guess that you weren't sure what to put in the query to filter for the days you list in the source.

Given your source snippet, I think its safe to infer that dwInt is being used as a bitmask, and DayOfWeek will have one bit position "set" to indicate a given day of week. On that basis, what you want to do is in the Where is perform a logical bitwise AND on DayOfWeek field with dwInt, and then check the result to be greater than 0, implying one of the desired day of week "bits" is set in your target field. I believe this would do the trick:

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

Please forgive if I have interpreted your question incorrectly.

Solution 4

[HasFlags] attribute is very interesting in a sense that it does not affect anything but .ToString() and (AFAIK) Enum.Parse() operations. Therefore for non-string operations it does not matter whether your enum type has [HasFlags] attribute. The way enums work in EF is that they are just cast to the underlying type and are treated as if they were one of the following integral types int64, int32, int16, byte, sbyte (note unsigned integral types are not supported by EDM and therefore enums with unsigned underlying type won't work and also in the database enum columns are just columns of a type that correspond to one of the above types). This means that basically any operation that is valid on an integral number values (of type supported by EF) is valid on enum values unless the compiler does not allow it (I don't think I am aware of any operation like this). This also means that whatever you wanted to put where your ???? are should work if it compiles (Sql Server supports bitwise operations)

Share:
15,665
tobias
Author by

tobias

Updated on June 05, 2022

Comments

  • tobias
    tobias about 2 years

    i have a enum type like below

      [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();