4

Closed

UpForGrabs: Query: Support Enum.HasFlag in LINQ to Entities [FixedIn6.1.0-alpha1] [AffectedLastRTM]

description

Enum.HasFlag is a useful and user friendly way to check if a number of bits are set for an enum variable, but if you try to use it in a entity framework Query you get an exception similar to the following:

_"An unhandled exception of type 'System.NotSupportedException' occurred in mscorlib.dll
Additional information: LINQ to Entities does not recognize the method 'Boolean HasFlag(System.Enum)' method, and this method cannot be translated into a store expression."_

I propose that support is added so that one can use the HasFlag function using entity framework. The implementation should be quite straight forward since bitwise operators are already supported. In short the expression "enumVariable.HasFlag(enumValue)" should be translated to "((enumVariable & enumValue) == enumValue)".

Here is some example code:
  [Flags]
    public enum BlogType
    {
        None = 0x0,
        Favorite = 0x1,
        Online =   0x2,
        Important =    0x4,
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Name { get; set; }
        public BlogType Type { get; set; }
    }

    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var db = new BloggingContext())
            {
                // Create and save a new Blog
                Console.Write("Enter a name for a new Blog: ");
                var name = Console.ReadLine();

                var blog = new Blog { Name = name, Type = BlogType.Favorite };
                db.Blogs.Add(blog);
                db.SaveChanges();

                // Display all Blogs from the database
                var query = from b in db.Blogs
                            orderby b.Name
                            select b;

                Console.WriteLine("All blogs in the database:");
                foreach (var item in query)
                {
                    Console.WriteLine(item.Name);
                }

                // Display all Blogs from the database (this works)
                query = from b in db.Blogs
                        where ((b.Type & BlogType.Favorite) == BlogType.Favorite)
                        orderby b.Name
                        select b;

                Console.WriteLine("All blogs in the database:");
                foreach (var item in query)
                {
                    Console.WriteLine(item.Name);
                }

                // Display all Blogs from the database (this don't work)
                query = from b in db.Blogs
                        where b.Type.HasFlag(BlogType.Favorite)
                        orderby b.Name
                        select b;

                Console.WriteLine("All blogs in the database:");
                foreach (var item in query)
                {
                    Console.WriteLine(item.Name);                
                }

                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
            }
        }
    }
Update: I found a correpsonding request at uservoice
http://data.uservoice.com/forums/72025-entity-framework-feature-suggestions/suggestions/3951293-support-enum-hasflag but it currenlt has so few votes nobody will se it unless they search for it
Closed Jan 16 at 12:30 AM by maumar
verified, closing

comments

RoMiller wrote Aug 5, 2013 at 11:48 PM

EF Team Triage: We agree that this would be good to support. Given where we are in the EF6 release we're moving this to 'Future' to consider for upcoming releases.

RogerAlsing wrote Nov 27, 2013 at 7:15 PM

Ill give it a try

divega wrote Nov 28, 2013 at 7:34 AM

Hi Roger,

Great to hear from you! Please read the details of our contribution process and remember to send a signed Contributor License Agreement if you haven't already.

Thanks,
Diego

RogerAlsing wrote Dec 8, 2013 at 1:02 PM

OK, I'm done, it works for the specified test case.
However, how should cases like this be treated?

where blog.Type.HasFlag(otherBlog.Type)

??
The current test case only assumes constant flag expression.

RogerAlsing wrote Dec 8, 2013 at 1:18 PM

NVM, covered those cases too now.

What do I do now?
My repo is here https://entityframework.codeplex.com/SourceControl/network/forks/RogerAlsing/HasFlags

Also, what about exceptions? what should be thrown incase of some unsupported expression is used?

divega wrote Dec 9, 2013 at 8:09 PM

Assigning to Pawel who will be processing Roger's pull request.

moozzyk wrote Dec 17, 2013 at 10:44 PM

This is now checked in. Changesets #0539f55, #bc5be08, #e360f24, #d8bbcc0, #7da39fc, #f913670, #23da501, #fda5454, #cf66017, #495279b, #b949849