Generate Linq Or Clause from List of Enumeration

c#, linq

Solution

You should make `Conditions` a `Flags` enum:

[Flags]
public enum Conditions {
    ByNone = 0,
    ByAlpha = 1,
    ByBeta = 2,
    ByGamma = 4
}

and change your ResultObject:

class ResultObject {
    public Conditions Conditions { get; set; }
    public string Name { get; set; }
}

and then you can say:

var conditions = new List<Conditions> { Conditions.ByAlpha, Conditions.ByGamma };
var matches = sampleCollection
                  .Where(x => conditions.Select(c => c & x != 0).Any());

This is the right design for the problem that you're trying to solve.

If for some reason you need to keep your current `ResultObject`, which I will now call `OldResultObject` for the sake of clarity:

class OldResultObject {
    public bool AlphaValue { get; set; }
    public bool BetaValue { get; set; }
    public bool GammaValue { get; set; }
    public string Name { get; set; }
}

it's easy to project that to a new `ResultObject`:

var resultObject = new ResultObject {
    Conditions =
        (oldResultObject.AlphaValue ? Conditions.ByAlpha : Conditions.ByNone) | 
        (oldResultObject.BetaValue ? Conditions.ByBeta : Conditions.ByNone) |
        (oldResultObject.GammaValue ? Conditions.ByGamma : Conditions.ByNone),
    Name = oldResult.Name;
}

so this is really very little effort on your part to redesign at all.

Problem

Greetings Overflowers, I am working on an application that allows for a user to generate a custom report and I have a scenario where I need to generate a Linq Or clause from a list of enumeration values. The problem I'm having is I cannot see an elegant way of generating the Or clause. For example: ``` //Enumeration of possible 'OR' conditions public enum Conditions { ByAlpha, ByBeta, ByGamma } //'Entity' I'm querying against. class ResultObject { public bool AlphaValue { get; set; } public bool BetaValue { get; set; } public bool GammaValue { get; set; } public string Name { get; set; } } class Program { static void Main(string[] args) { //Create list of desired conditions. //Basically I want this to mimic the query, // "Show me all of the ResultObjects where the AlphaValue is true or the GammaValue is true". var conditions = new List<Conditions> { Conditions.ByAlpha, Conditions.ByGamma }; //Sample collection of objects. This would normally be a collection of EF entities. var sampleCollection = new List<ResultObject> { new ResultObject { Name = "Sample 1", AlphaValue = true, BetaValue = true, GammaValue = true, }, new ResultObject { Name = "Sample 2", AlphaValue = false, BetaValue = false, GammaValue = false, }, new ResultObject { Name = "Sample 3", AlphaValue = true, BetaValue = false, GammaValue = true, } }; var sampleCollectionQueryable = sampleCollection.AsQueryable(); //This should filter the sampleCollection down to containing only the //"Sample 3" ResultObject; instead, it filters out all of the ResultObjects. var query = GenerateOrClause(sampleCollectionQueryable, conditions); } static IQueryable<ResultObject> GenerateOrClause(IQueryable<ResultObject> query, List<Conditions> conditions) { //This approach generates a series of AND statements, instead I need a series of OR statements //for each condition. foreach (var condition in conditions) { switch (condition) { case Conditions.ByAlpha: query = query.Where(x => x.AlphaValue); break; case Conditions.ByBeta: query = query.Where(x => x.BetaValue); break; case Conditions.ByGamma: query = query.Where(x => x.GammaValue); break; default: throw new ArgumentOutOfRangeException(); } } return query; } } ``` Any ideas?

Original source