Friday, 15 April 2011

c# - Transform LINQ to normal Foreach -



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:

create 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