c# - Generate Linq Or Clause from List of Enumeration -
greetings overflowers,
i working on application allows user generate custom report , have scenario need generate linq or clause list of enumeration values. problem i'm having cannot see elegant way of generating 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 want mimic query,          // "show me of resultobjects alphavalue true or gammavalue true".         var conditions = new list<conditions>         {             conditions.byalpha,             conditions.bygamma         };          //sample collection of objects.  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 samplecollection down containing          //"sample 3" resultobject; instead, filters out of resultobjects.         var query = generateorclause(samplecollectionqueryable, conditions);     }      static iqueryable<resultobject> generateorclause(iqueryable<resultobject> query, list<conditions> conditions)     {         //this approach generates series of , statements, instead need 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?
you should make conditions flags enum:
[flags] public enum conditions {     bynone = 0,     byalpha = 1,     bybeta = 2,     bygamma = 4 }   and change resultobject:
class resultobject {     public conditions conditions { get; set; }     public string name { get; set; } }   and 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 right design problem you're trying solve.
if reason need keep current resultobject, call oldresultobject 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 project 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 very little effort on part redesign @ all.
Comments
Post a Comment