zoukankan      html  css  js  c++  java
  • Entity Framework and Enum Flags

    If you have ever had the need to store one or more possible values in a single field, you may have used the [Flags] attribute on an enum in C# which would look something like this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [Flags]
    public enum ColorFlags
    {
        Red = 1,
        Orange = 2,
        Yellow = 4,
        Green = 8,
        Blue = 16,
        Indigo = 32,
        Violet = 64
    }

    The numeric values that we assign are important, because it allows us to do bit-wise operations on the number.  The values themselves can easily be calculated by raising 2 to the power of a zero-based sequence of numbers.  So this:

    2⁰, 2¹, 2², 2³, 2⁴, 2⁵, 2⁶

    yields this (yes, 2 to the zero power is one):

    1, 2, 4, 8, 16, 32, 64

    When we talk about doing a bit-wise comparison, I find it easier to understand when I see these numbers written in binary:

    1
    2
    3
    4
    5
    6
    7
    0000001 = 1
    0000010 = 2
    0000100 = 4
    0001000 = 8
    0010000 = 16
    0100000 = 32
    1000000 = 64

    As you can see, each of these numbers hold only a single 1 value in each position.  This is what will allow us to store any combination of these values and still determine which of the individual values a number contains.  For example, the value 3 (0000011) indicates that the two first options are set (Red and Orange).

    When we store this value in the database, it is simply a number and for our example, we will never exceed the sum of those values (1111111 in binary, or 127 in decimal) so we could store it as a tinyint, but a smallint would give us room to add more values without the need to change our data type.

    If we are only working with our Flags Enum in C#, we can use the Enum.HasFlag() method to determine if our value has a certain enum value:

    1
    2
    3
    4
    5
    public bool IsPrimaryColor(ColorFlags color)
    {
        ColorFlags primaryColors = ColorFlags.Blue | ColorFlags.Green | ColorFlags.Red;
        return primaryColors.HasFlag(color);
    }

    In the method above, we use a bit-wise OR to combine the values of the primary colors and then use HasFlag() to see if the color passed into the method matches any of the binary values of the primary colors.  And since we are using a ColorFlags enum as the parameter, you can even use HasFlag to compare any combination of values.

    Flags and Entity Framework

    This all works great in C#, but we have to take a different approach if we are using Linq to Entities because HasFlag() is not available to us.  Fortunately, SQL Server and Entity Framework support bit-wise operations, so we can use the single “&” to see if the stored value has the bit position that matches our value.

    The example below shows how we would query for records that match ALL of the specified colors.  It will include records that may have additional colors specified, but they must have at a minimum Blue and Red set.  This is because we are comparing the AND-ed bits against the original colorsToMatch value:

    1
    2
    3
    // Only return records that have ALL specified colors
    ColorFlags colorsToMatch = ColorFlags.Blue | ColorFlags.Red;
    var matchingColors = db.Cars.Where(c => c.Color & colorsToMatch == colorsToMatch);

    If we instead want to return cars that have ANY of the specified colors, we just need to check to see if the & operation is not zero.  If any of the bit positions match, it will return the sum of those values, but we don’t care if it is exactly the same as the colorsToMatch value, only that it isn’t zero meaning that there is at least one color that matches:

    1
    2
    3
    // Return records that have ANY of the specified colors
    ColorFlags colorsToMatch = ColorFlags.Blue | ColorFlags.Red;
    var matchingColors = db.Cars.Where(c => c.Color & colorsToMatch != 0);

     Additional Recommendations

    A few things to keep in mind when using Flag Enums with Entity Framework:

    1. Start your Flags Enum values with one, not zero.  Otherwise, you won’t be able to match the first value.  The exception is if you want to provide a “None” option.
    2. Remember that your data will be stored as a number in the database so use a datatype that can accommodate all of your values with room to add more, if necessary.
    3. Be aware of the differences between matching ANY of the flag values vs. ALL of the flag values.


    转载:http://blog.falafel.com/entity-framework-enum-flags/
    The following two tabs change content belo




  • 相关阅读:
    windows下 python2 和python3 共存
    利用xshell远程连接centos安装oracle11g时在图形界面登录
    本地导入/导出远程oracle数据库
    centos7安装桌面环境
    普通用户修改.bash_profile 权限问题
    centos7 安装oracle11g
    Unable to fetch some archives ,maybe run apt-get update or try with --fix-missing?
    spring mvc 使用ehcache
    leaflet创建简单地图
    【BZOJ 3958】 3958: [WF2011]Mummy Madness (二分+扫描线、线段树)
  • 原文地址:https://www.cnblogs.com/wuyicqb/p/5514108.html
Copyright © 2011-2022 走看看