Not sure if this is possible or if I'm expressing correctly what I'm looking for, but I have the following piece of code in my library repeatedly and would like to practice some DRY. I have set of SQL Server tables that I'm querying based on a simple user-supplied search field ala Google. I'm using LINQ to compose the final query based on what's in the search string. I'm looking for a way to use generics and passed in lambda functions to create a reusable routine out of this:
string[] arrayOfQueryTerms = getsTheArray();
var somequery = from q in dataContext.MyTable
select q;
if (arrayOfQueryTerms.Length == 1)
{
somequery = somequery.Where<MyTableEntity>(
e => e.FieldName.StartsWith(arrayOfQueryTerms[0]));
}
else
{
foreach(string queryTerm in arrayOfQueryTerms)
{
if (!String.IsNullOrEmpty(queryTerm))
{
somequery = somequery
.Where<MyTableEntity>(
e => e.FieldName.Contains(queryTerm));
}
}
}
I was hoping to create a generic method with signature that looks something like:
private IQueryable<T> getQuery(
T MyTableEntity, string[] arrayOfQueryTerms, Func<T, bool> predicate)
I'm using the same search strategy across all my tables, so the only thing that really differs from usage to usage is the MyTable & MyTableEntity searched and the FieldName searched. Does this make sense? Is there a way with LINQ to dynamically pass in the name of the field to query in the where clause? Or can I pass in this as a predicate lambda?
e => e.FieldName.Contains(queryTerm)
I realize there a million and a half ways to do this in SQL, probably easier, but I'd love to keep everything in the LINQ family for this one. Also, I feel that generics should be handy for a problem like this. Any ideas?
It sounds like you're looking for Dynamic Linq. Take a look here. This allows you to pass strings as arguments to the query methods, like:
var query = dataSource.Where("CategoryID == 2 && UnitPrice > 3")
.OrderBy("SupplierID");
Edit: Another set of posts on this subject, using C# 4's Dynamic support: Part 1 and Part 2.
What it sounds like is you want basically a conditional predicate builder..
I hope you can mold this into something you are looking for, good luck!
http://www.albahari.com/nutshell/predicatebuilder.aspx
You might want to look at expression trees:
IQueryable<T> getQuery<T>(T myTableEntity, string[] arrayOfQueryTerms, Expression<Func<T, bool>> predicate)
{ var fieldOrProperty = getMemberInfo(predicate);
/* ... */
}
MemberInfo getmemberInfo<T>(Expression<Func<T,bool> expr)
{ var memberExpr = expr as MemberExpression;
if (memberExpr != null) return memberExpr.Member;
throw new ArgumentException();
}
var q = getQuery<FooTable>(foo, new[]{"Bar","Baz"}, x=>x.FieldName);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With