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