Help with linq

  • Thread starter Thread starter Julie
  • Start date Start date
J

Julie

I have a situation where I have many methods that have a similar linq
expression. Is there a way to re-write to be more efficient?

int Qty1()
{
return (from each in MyData where each.Item1 == 1 select each).Count();
}

int Qty2()
{
return (from each in MyData where each.Item2 == 1 select each).Count();
}

int Qty3()
{
return (from each in MyData where each.Item3 == 1 select each).Count();
}

etc.


What I'd like is a generic Qty method that takes the 'where' condition:

int Qty(??? condition)
{
return (from each in MyData where condition select each).Count();
}

But I have no idea how to do this.

Thanks!
 
Peter said:
That depends a bit on the exact structure of the code, which you don't
show. But, assuming there's nothing too obstrusive going on, something
like this should work:

int Qty(Func<MyElement, bool> condition)
{
return MyData.Count(condition);
}

Assume MyData implements IEnumerable<MyElement>. In other words, just
replace "MyElement" with whatever type each element of MyData actually is.

Then in whatever code you want to use the method, you could call it like
this:

int result = Qty(x => x.Item1 == 1);

Alternatively, keep the methods named "Qty1", "Qty2", etc. and re-write
them to call Qty():

int Qty1()
{
return Qty(x => x.Item1 == 1);
}

Or, you could go straight to the source, and just call
Enumerable.Count() directly:

int result = MyData.Count(x => x.Item == 1);

If the property you're checking is always compared to "1", as your
example suggests, you can fold the comparison into the helper method
instead of making the caller provide it:

int Qty(Func<MyElement, int> funcGetProperty)
{
return MyData.Count(x => funcGetProperty(x) == 1);
}

Then call as so:

int result = Qty(x => x.Item1);

Mix and match the above variations to suit your needs. :)

Note that in all of the above examples, there's no need to write a LINQ
query. The Enumerable.Count() extension method includes an overload
that provides the same filtering behavior you're using the LINQ query to
do.

Pete

Ok, thanks Pete, that got me a lot further. I prefer the second
solution using the funcGetProperty, but it I couldn't get it to work for
me. I neglected to mention that my I'm using LINQ to SQL, and when
evaluating funcGetProperty, I get an exception

"System.Object DynamicInvoke(System.Object[])' has no supported
translation to SQL."

In looking further into the exception, the error makes sense when
applied to SQL (to a non-SQL source, the code works fine). Are you
aware of a way to convert it to work w/ SQL?

Also, your first solution works fine w/ LINQ to SQL, so at least I've
cleaned up my code a lot from where I was before.

Thanks!
 
Back
Top