Reputation: 605
I have the following 2 methods that i thing could be compressed in one method using generics. What i have tried can not compile. Can someone let me know how this can be done? I need to check that 2 differents field of the table AgeLengths have at least one values. Str_table has one to many relationship with AgeLengths.
public static bool HasMeanWeight(int id)
{
MyDataContext dc = new MyDataContext ();
return (from s in dc.Str_table
where s.SId == id
select s.AgeLengths
.Where(a => a.MeanWeight != null ).Any() == true
).FirstOrDefault();
}
public static bool HasNumbersData(int id)
{
MyDataContext dc = new MyDataContext ();
return (from s in dc.Str_table
where s.sId == id
select s.AgeLengths
.Where(a => a.Numbers != null).Any() == true
).FirstOrDefault();
}
Thanks in advance B
Upvotes: 3
Views: 160
Reputation: 37770
If you're using some DataContext
, you're using IQueryable<T>
, and you're very limited with stuff you can write in your expressions. So, you need to pass an expression to your method, not a predicate itself:
static bool HasData(int id, Expression<Func<AgeLength, bool>> predicate)
{
using (MyDataContext dc = new MyDataContext())
{
return (from s in dc.Str_table
where s.sId == id
select s.AgeLengths
.Any(predicate)
).FirstOrDefault();
}
}
Besides:
Any
overload, that accepts predicate expression;using
);someBoolExpression == true
; just write someBoolExpression
.Than you can call this method like this:
HasData(1, a => a.MeanWeight != null);
HasData(1, a => a => a.Numbers != null);
Note, that the second argument is a lambda expression, not a method.
This is because of lazy nature of queries: you're providing a set of expressions, and the corresponding provider converts them into appropriate SQL.
Upvotes: 3
Reputation: 64487
Update: Apologies, I didn't realise this was linq to sql. Dennis's answer appears to be on the mark.
Try injecting a Func<T, TResult>
to inject the differing code:
public static bool HasData(int id, Func<AgeLength, object> selector)
{
MyDataContext dc = new MyDataContext ();
return (from s in dc.Str_table
where s.sId == id
select s.AgeLengths
.Where(a => selector(a) != null)
.Any())
.FirstOrDefault();
}
And call like so:
HasData(1, a => a.Numbers);
HasData(1, a => a.MeanWeight);
If the Numbers
and MeanWeight
properties are in the same inheritance hierarchy, then you can substitute object
with something more useful, but in this instance object
is fine as you are just testing for null.
Upvotes: 5