Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fluent Nhibernate expression to select on flagged enum

I have a domain entity that has a flagged enum as a property. The flagged enum is the target audience for the these entities. The user then has a flagged enum value of the entities they should see. I am trying to figure out the correct expression to select entities that meet the target audience for the user.

public class File
{
    public virtual TargetAudience TargetAudience { get; set; }
}

[Flags]
public enum TargetAudience
{
    Audience1 = 1,
    Audience2 = 2,
    Audience3 = 4,
    Audience4 = 8
}

Expression: (This works when performed on a IList<File>, but doesn't work on a query to the database.)

public Expression<Func<File, bool>> Expression
{
     get { return ((x.TargetAudience & UserTargetedAudience) > 0); }
}

Any suggestions would be helpful.

like image 703
mbalkema Avatar asked Apr 07 '10 13:04

mbalkema


1 Answers

In what way does it not work in a query to the database?

You aren't showing your full implementation nor your mapping. Are you persisting TargetAudience as a numeric datatype?

Unless you are jumping through some hoops to do so, your enum will be stored as text in the database, so you can't perform bitwise operations on it. (This behaviour is contrary to some of what I've seen around blogs, etc., so I don't know (a) if it has changed since prior versions, (b) if it is somehow unique to the SQLite provider that I'm using, or (c) if it is mapped this way by Fluent NHibernate.)

You can perform a textual comparison. Combined flags get stored as a comma-separated list, so TargetAudience.Audience4 | TargetAudience.Audience1 would be persisted not as 9, but as Audience1, Audience4. Note that it gets persisted in ascending order, even though I specified them in reverse order.

var query = session.Linq<File>()
    .Where(f => f.TargetAudience.ToString() == "Audience1, Audience4");

You could write a few [extension] methods in short order that would encapsulate the nastiness of doing these textual comparisons.

edit:

See How do you map an enum as an int value with fluent NHibernate? for information about persisting enums as integers

like image 159
Jay Avatar answered Sep 29 '22 19:09

Jay