c# - Difficulty with LINQ -
i'm having difficulty ienumerable , linq. perhaps don't understand fully.
i have data source of fake files ("plumfile"), , filters. each filter has fits(plumfile)
determines if argument fits filter. each filter has enum indicating if it's "and", "or", or "not".
here how i'm trying combine filters query:
public observablecollection<plumfile> foundfiles { { observablecollection<plumfile> searchresults = new observablecollection<plumfile>(); // data source ienumerable<plumfile> query = plumdata.getfiles(); foreach (filterconstraint filter in filters) { // debugging ilist<plumfile> oldquery = query.tolist(); switch (filter.querycombiningrule) { case filterconstraint.queryrule.and: query = query.where(file => filter.fits(file)); break; case filterconstraint.queryrule.or: query = query.concat(plumdata.getfiles().where(file => filter.fits(file))); break; // how want 'not'? case filterconstraint.queryrule.not: query = query.where(file => !filter.fits(file)); break; } // debugging ilist<plumfile> currquery = query.tolist(); } query = query.distinct(); foreach (plumfile file in query) { searchresults.add(file); } return searchresults; } }
i'm not sure i'm doing wrong. queries, works fine. others, fails.
if have single "and" filter, works fine. add "not" filter shouldn't filter out selected, removed. why this?
(i'm doing silverlight 4 app, don't think matters.)
update: 1 example of filter constraint:
public class namefilterconstraint : filterconstraint { public string name { get; set; } public override bool fits(plumfile plumfile) { return plumfile.name.contains(name); } public override string description { { return tostring(); } } public override string tostring() { return string.format("name contains '{0}'", name); } }
update 2: here non-linq version doesn't have bugs mentioned earlier:
public observablecollection<plumfile> foundfiles { { observablecollection<plumfile> searchresults = new observablecollection<plumfile>(plumdata.getfiles().tolist()); foreach (filterconstraint filter in filters) { switch (filter.querycombiningrule) { case filterconstraint.queryrule.and: foreach (plumfile file in searchresults.tolist()) { if (! filter.fits(file)) { searchresults.remove(file); } } break; case filterconstraint.queryrule.or: foreach (plumfile file in plumdata.getfiles()) { if (filter.fits(file)) { searchresults.add(file); } } break; case filterconstraint.queryrule.not: foreach (plumfile file in searchresults.tolist()) { if (filter.fits(file)) { searchresults.remove(file); } } break; } } return new observablecollection<plumfile>(searchresults.distinct()); } }
so, guess problem solved, although i'm still curious doing wrong linq. perhaps intentions (made clear in last example) not translated linq properly?
just guess here, wonder if capture/closure issue. try this:
public observablecollection<plumfile> foundfiles { { observablecollection<plumfile> searchresults = new observablecollection<plumfile>(); // data source ienumerable<plumfile> query = plumdata.getfiles(); foreach (filterconstraint filter in filters) { var localfilter = filter; // debugging ilist<plumfile> oldquery = query.tolist(); switch (filter.querycombiningrule) { case filterconstraint.queryrule.and: query = query.where(file => filter.fits(file)); break; case filterconstraint.queryrule.or: query = query.concat(plumdata.getfiles().where(file => localfilter.fits(file))); break; // how want 'not'? case filterconstraint.queryrule.not: query = query.where(file => !localfilter.fits(file)); break; } // debugging ilist<plumfile> currquery = query.tolist(); } query = query.distinct(); foreach (plumfile file in query) { searchresults.add(file); } return searchresults; } }
Comments
Post a Comment