c# - Transform LINQ to normal Foreach -
i found below piece of code in 1 of our project. stuck 2 days :-( trying understand aggregate & linqkit expand.
can help in transforming below linq normal foreach operation?
public expression<func<purchase, bool>> fortarget(list<string> idlist) { expression<func<purchase, string>> fc = p => p.clientid; expression<func<purchase, bool>> predicate = m => false; homecoming idlist.aggregate(predicate, (p, id) => p.or(m => fc.invoke(m) == id), p => p.expand()); } internal class purchase { public int cost { get; set; } public string description { get; set; } public string clientid { get; set; } } public class client { public string id { get; set; } }
or atleast, pointer on linq look doing on list, much helpful.
return idlist.aggregate(predicate, (p, id) => p.or(m => fc.invoke(m) == id), p => p.expand());
the function iterates on collection of items , builds predicate adding or
status each clientid
property value.
in versions of linq2sql there no back upwards method contains
weren't able perform query this:
ienumerable<purchase> purchases = loadselecteditems(); var clientids = purchases.select( p => p.clientid ).toarray(); var results = db.clients.where( c => clientids.contains( c.id )); // did not work.
the workaround problem create predicate check using or
whether id
match specific value. so, above example, if clientids = {1, 2, 3}
where
clause written as:
var results = db.clients.where( c => c.id == 1 || c.id == 2 || c.id == 3);
as can see, kind of statement not elegant, becomes unreadable when collection of values check against (i. e. clientids
) big and, important, cannot know priori values hardcode them. so, overcome problem, solution generalize above predicate variable collection of values. , done next algorithm:
expression
returns false
; if homecoming true
compiler short-circuit evaluation (because we're using or
) , homecoming true items; for each item in collection of values add together or
clause value of item. now, illustration can converted foreach way:
// start predicate returning false // seed of aggregate method expression<func<purchase, bool>> predicate = m => false; // now, iterate collection , build total predicate foreach( var id in idlist) { // build predicate invoking function returns client id of // purchase , comparing value of current id idlist predicate = predicate.or(item => item.clientid == id); }
hope helps.
c# linq linqkit
No comments:
Post a Comment