Dynamically Build EF Query - c#

I am working on a dynamic query solution for a project. I want to avoid a bunch of if/else or switch statements just to change the [DynamicFieldName] part of these queries.
IQueryable<MyDataType> allItems = (from item in Context.MyDataTypes select item);
foreach (QueryEntry currentEntry in query.Fields)
{
allItems = allItems.Where(item => item.[DynamicFieldName] == currentEntry.Value);
}
The user gets to build the query via the GUI that has a variable number of fields. In the end, they will also have a variety of comparisons to choose from (Less than, greater than, equal, contains, etc.) that vary by data type.
What method can I use to build this programatically in a nice reusable fashion?

Have a look at this code:
public static class CustomQueryBuilder
{
//todo: add more operations
public enum Operator
{
Equal = 0,
GreaterThan = 1,
LesserThan = 2
}
public static IQueryable<T> Where<T>(this IQueryable<T> query, string property, Operator operation, object value)
{
//it's an item which property we are referring to
ParameterExpression parameter = Expression.Parameter(typeof(T));
//this stands for "item.property"
Expression prop = Expression.Property(parameter, property);
//wrapping our value to use it in lambda
ConstantExpression constant = Expression.Constant(value);
Expression expression;
//creating the operation
//todo: add more cases
switch (operation)
{
case Operator.Equal:
expression = Expression.Equal(prop, constant);
break;
case Operator.GreaterThan:
expression = Expression.GreaterThan(prop, constant);
break;
case Operator.LesserThan:
expression = Expression.LessThan(prop, constant);
break;
default:
throw new ArgumentException("Invalid operation specified");
}
//create lambda ready to use in queries
var lambda = Expression.Lambda<Func<T, bool>>(expression, parameter);
return query.Where(lambda);
}
}
Usage
var users = context
.Users
.Where("Name", CustomQueryBuilder.Operator.Equal, "User")
.ToList();
Which is equal to
var users = context
.Users
.Where(u => u.Name == "User")
.ToList();

Related

Dynamic GroupBy using expression in .net core

I wrote an extension method that makes an expression based on condition, but when the condition is groupby, the result is order by !!!
what am I wrong?
here is my method:
public static IQueryable<T> NewWhere<T, U>(this IQueryable<T> source, string prop, U value, string condition)
{
MethodInfo method;
Expression<Func<T, bool>> lambda = null;
Expression body = null;
string groupSelector = null;
var type = typeof(T);
var parameter = Expression.Parameter(type, "p");
var property = Expression.Property(parameter, prop);
var constant = Expression.Constant(value, typeof(U));
if (condition == "GreaterThan")
body = Expression.GreaterThan(property, constant);
else if (condition == "LessThan")
body = Expression.LessThan(property, constant);
else if (condition == "Equals")
body = Expression.Equal(property, constant);
//For implement sql like command we need them
else if (condition == "StartsWith") {
method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
body = Expression.Call(property, method, constant);
}
else if (condition == "EndsWith")
{
method = typeof(string).GetMethod("EndsWith", new[] { typeof(string) });
body = Expression.Call(property, method, constant);
}
else if (condition == "Contains")
{
method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
body = Expression.Call(property, method, constant);
}
//For implement sql like command we need them
//group by only one field
if (condition == "GroupBy")
groupSelector = prop;
else
lambda = Expression.Lambda<Func<T, bool>>(body, new[] { parameter });
//return the grouped by result or not grouped by
if (groupSelector != null)
{
var selectorExp = Expression.Lambda<Func<T, U>>(property, new ParameterExpression[] { parameter });
source = source.GroupBy(selectorExp).SelectMany(g => g);
//source.GroupBy(e => e.GetType().GetProperty(groupSelector)).SelectMany(gr => gr);
}
else
source = source.Where(lambda);
return source;
}
but when i run the mthod with GroupBy condition, the result is:
SELECT [e].[Id], [e].[Year]
FROM [org].[Data] AS [e]
ORDER BY [e].[Year]
i don't know why its happened?
TL;DR;: Entitity Framework uses the query because it is the most efficient way to get what you want.
What Entity Framework does is to translate your LINQ query into SQL. Check this line of your code:
source = source.GroupBy(selectorExp).SelectMany(g => g);
You are grouping (probably by year) and then you select all the items of the group. You are actually not requesting a grouped result set, you are expecting all items in all groups in a single flat result set. If EF would first request the groups and then request the group items, it would first have to select all groups:
SELECT [e].[Year]
FROM [org].[Data] AS [e]
GROUP BY [e].[Year]
Then it would have to get the group items in one query for each group:
SELECT [e].[Id]
FROM [org].[Data] AS [e]
WHERE [e].[Year] = --Value
That of course would be very inefficient (especially since you flatten the list anyway with SelectMany), so EF will just get the values ordered by your grouping predicate and group them during query execution (or in this case not group them at all, since you are requesting a flat list). Once the query is executed, EF can just start at the top of the result set and start a new group every time it encounters a new year.
When you are using EF queries, you have to accept that you won't have control over your SQL. If you want that, create stored procedures and run them from EF.

Difference in how LINQ to Entities and LINQ to Objects handle casts

I have recently joined a project where a Sort method was conditionally passing in a lambda expression to a LINQ query to define which property should be sorted on. The problem was that the lambda expression was being passed in a Func<TEntity, Object> and not in an Expression<Func<TEntity, Object>> so that the sorting was taking place in memory and not on the database (because the overload of OrderBy that takes an IEnumerable is called). This is the version in SortWithDelegate (see below).
When I use an Expression<Func<TEntity, Object>> (see SortWithExpression below) then, when a string property is passed in the orderBy parameter, the ordering is done correctly in the database. However, when I try to sort on an integer (or datetime) using Expression<Func<TEntity, Object>> I get the following error:
Unable to cast the type 'System.Int32' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types.
To avoid this I have to wrap the integer or datetime field to be sorted on inside an anonymous type like so: orderByFunc = sl => new {sl.ParentUnit.Id};. I understand I need to do this as the return type of the Func is Object. However, what I do not understand is why I need to do this when working with the LINQ to Entities provider but not the LINQ to Objects provider?
void Main()
{
var _context = new MyContext();
string sortProperty = "Id";
bool sortAscending = false;
IQueryable<Qualification> qualifications = _context.Qualifications.Include(q => q.ParentUnit);
qualifications = SortWithExpression(sortProperty, sortAscending, qualifications);
qualifications.Dump();
}
private static IQueryable<Qualification> SortWithDelegate(string orderBy, bool sortAscending, IQueryable<Qualification> qualificationsQuery)
{
Func<Qualification, Object> orderByFunc;
switch (orderBy)
{
case "Name":
orderByFunc = sl => sl.Name;
break;
case "ParentUnit":
orderByFunc = sl => sl.ParentUnit.Name;
break;
case "Id":
orderByFunc = sl => sl.ParentUnit.Id;
break;
case "Created":
orderByFunc = sl => sl.Created;
break;
default:
orderByFunc = sl => sl.Name;
break;
}
qualificationsQuery = sortAscending
? qualificationsQuery.OrderBy(orderByFunc).AsQueryable()
: qualificationsQuery.OrderByDescending(orderByFunc).AsQueryable();
return qualificationsQuery;
}
private static IQueryable<Qualification> SortWithExpression(string orderBy, bool sortAscending, IQueryable<Qualification> qualificationsQuery)
{
Expression<Func<Qualification, Object>> orderByFunc;
switch (orderBy)
{
case "Name":
orderByFunc = sl => sl.Name;
break;
case "ParentUnit":
orderByFunc = sl => sl.ParentUnit.Name;
break;
case "Id":
orderByFunc = sl => new {sl.ParentUnit.Id};
break;
case "Created":
orderByFunc = sl => new {sl.Created};
break;
default:
orderByFunc = sl => sl.Name;
break;
}
qualificationsQuery = sortAscending
? qualificationsQuery.OrderBy(orderByFunc)
: qualificationsQuery.OrderByDescending(orderByFunc);
return qualificationsQuery;
}
Added
Just thought I'd add my own solution to this problem. To avoid boxing int and datetime I've created a generic extension method on IQueryable<T> to which I pass in the lambda expression to indicate the sort field and a boolean indicating whether the sort order should be ascending or not:
public static IQueryable<TSource> OrderBy<TSource, TResult>(this IQueryable<TSource> query, Expression<Func<TSource, TResult>> func, bool sortAscending)
{
return sortAscending ?
query.OrderBy(func) :
query.OrderByDescending(func);
}
private static IQueryable<Qualification> Sort(string orderBy, bool sortAscending, IQueryable<Qualification> qualificationsQuery)
{
switch (orderBy)
{
case "Name":
return qualificationsQuery.OrderBy(sl => sl.Name, sortAscending);
case "ParentUnit":
return qualificationsQuery.OrderBy(s1 => s1.ParentUnit.Name, sortAscending);
default:
return qualificationsQuery.OrderBy(sl => sl.Name, sortAscending);
}
}
Expression trees as their name implies are expression about doing something.you can visit the expressions and interpret them to your own business or like lambda expressions you can compile them and invoke as a delegate.
When you pass the expression to orderby method in Linq to Entities, it will be visited by Linq to Entities and in your case that "Int32 to Object" exception will be generated because the way it is interpreted as a MemberInfo that turn into a column name for the database query. But when you use it as a Func delegate, it can not be translated and it will be invoked as a delegate for comparison in orderby method's sort algorithm.

How to build a collection filter via expression trees in c#

I'm building a filtering system for UserProfiles based on known properties but unknown (until runtime) combination of filtering conditions.
In my previous question How do I create a generic Expression that has an expression as a parameter, I've figured out a way to have a FilterDefinition for any value property reachable from User entity via navigation properties (i.e. (User)u=> u.NavigationProperty.AnotherNavigationProperty.SomeValue)
and I have a method that can return a predicate as Expression<Func<User,bool>> for a given property, operation ( > < == etc ) and a value.
Now the time has come to filter them on collection properties as well.
Say for example User has CheckedOutBooks collection (which is a total fiction, but will do)
And I need to create a filter definition for Name property of CheckedOutBooks collection on User object.
What I have:
A collection of Users
User class has a collection of Books
now I would like to create a method
Expression<Func<User,bool>> GetPredicate(Expression<User,TProperty>, Operations operation, TProperty value)
That I can call like GetPredicate(u=>u.Books.Select(b=>b.Name), Operations.Contains, "C# in a nutshell")
and get an expression back similar to
u=>u.Books.Any(b=>b.Name == "C# in a nutshell")
I'm thinking maybe it will be easier to split first parameter in two to achieve this.
Maybe u=>u.Books and b=>b.Name will do better?
EDIT:
what I got so far:
class FilterDefinitionForCollectionPropertyValues<T>:FilterDefinition, IUserFilter
{
public Expression<Func<UserProfile, IEnumerable<T>>> CollectionSelector { get; set; }
public Expression<Func<T, string>> CollectionPropertySelector { get; set; }
public Expression<Func<Profile.UserProfile, bool>> GetFilterPredicateFor(FilterOperations operation, string value)
{
var propertyParameter = CollectionPropertySelector.Parameters[0];
var collectionParameter = CollectionSelector.Parameters[0];
// building predicate to supply to Enumerable.Any() method
var left = CollectionPropertySelector.Body;
var right = Expression.Constant(value);
var innerLambda = Expression.Equal(left, right);
Expression<Func<T, bool>> innerFunction = Expression.Lambda<Func<T, bool>>(innerLambda, propertyParameter);
var method = typeof(Enumerable).GetMethods().Where(m => m.Name == "Any" && m.GetParameters().Length == 2).Single().MakeGenericMethod(typeof(T));
var outerLambda = Expression.Call(method, Expression.Property(collectionParameter, typeof(UserProfile).GetProperty("StaticSegments")), innerFunction);
throw new NotImplementedException();
}
}
Now this one works awesomely and does exactly what's needed, now the only thing I need to figure out is how to replace typeof(UserProfile).GetProperty("StaticSegments")) somehow to use CollectionPropertySelector that is in current example would be (UserProfile)u=>u.StaticSegments
You're almost done. Now you just need to do a little trick - wrap your CollectionPropertySelector lambda expression in the CollectionSelector lambda expression.
Expression<Func<TParent,bool>> Wrap<TParent,TElement>(Expression<Func<TParent, IEnumerable<TElement>>> collection, Expression<Func<TElement, bool>> isOne, Expression<Func<IEnumerable<TElement>, Func<TElement, bool>, bool>> isAny)
{
var parent = Expression.Parameter(typeof(TParent), "parent");
return
(Expression<Func<TParent, bool>>)Expression.Lambda
(
Expression.Invoke
(
isAny,
Expression.Invoke
(
collection,
parent
),
isOne
),
parent
);
}
You may have to change this a bit to be used for your particular scenario, but the idea should be clear. My test looked basically like this:
var user = new User { Books = new List<string> { "Book 1", "Book 2" }};
var query = Wrap<User, string>(u => u.Books, b => b.Contains("Bookx"), (collection, condition) => collection.Any(condition));
So you specify the collection selector, predicate and predicate operator, and you're done.
I've written it as a generic method for clarity, but it's dynamic, not strongly typed in essence, so it should be pretty easy to change it to non-generic, if you need that.
Ok I've got it solved for myself.
And I published it to gitHub:
https://github.com/Alexander-Taran/Lambda-Magic-Filters
Given the filter definition class (not reafactored to support properties other than string so far, but will do later):
class FilterDefinitionForCollectionPropertyValues<T>:FilterDefinition, IUserFilter
{
//This guy just points to a collection property
public Expression<Func<UserProfile, IEnumerable<T>>> CollectionSelector { get; set; }
// This one points to a property of a member of that collection.
public Expression<Func<T, string>> CollectionPropertySelector { get; set; }
//This one does the heavy work of building a predicate based on a collection,
//it's member property, operation type and a valaue
public System.Linq.Expressions.Expression<Func<Profile.UserProfile, bool>> GetFilterPredicateFor(FilterOperations operation, string value)
{
var getExpressionBody = CollectionPropertySelector.Body as MemberExpression;
if (getExpressionBody == null)
{
throw new Exception("getExpressionBody is not MemberExpression: " + CollectionPropertySelector.Body);
}
var propertyParameter = CollectionPropertySelector.Parameters[0];
var collectionParameter = CollectionSelector.Parameters[0];
var left = CollectionPropertySelector.Body;
var right = Expression.Constant(value);
// this is so far hardcoded, but might be changed later based on operation type
// as well as a "method" below
var innerLambda = Expression.Equal(left, right);
Expression<Func<T, bool>> innerFunction = Expression.Lambda<Func<T, bool>>(innerLambda, propertyParameter);
// this is hadrcoded again, but maybe changed later when other type of operation will be needed
var method = typeof(Enumerable).GetMethods().Where(m => m.Name == "Any" && m.GetParameters().Length == 2).Single().MakeGenericMethod(typeof(T));
var outerLambda = Expression.Call(method, Expression.Property(collectionParameter, (CollectionSelector.Body as MemberExpression).Member as System.Reflection.PropertyInfo), innerFunction);
var result = Expression.Lambda<Func<UserProfile, bool>>(outerLambda, collectionParameter);
return result;
}
}

Dynamic linq query expression tree for sql IN clause using Entity framework

I want to create a dynamic linq expression for sql IN clause in EF 6.0 with code first approch. Note that i am new to Expressions. What i want to achive is
select * from Courses where CourseId in (1, 2, 3, 4)
//CourseId is integer
The normal linq query looks like this. But i want to query it dynamically
string[] ids = new string[]{"1", "2", "3", "4"};
var courselist = DBEntities.Courses.Where(c => ids.Contains(SqlFunctions.StringConvert((decimal?)c.CourseId)))
There are two ways to make dynamic expression.
1) one ways is to loop through ids and make expressions
The below code will create the following expression in debug view
{f => ((StringConvert(Convert(f.CourseId)).Equals("23") Or StringConvert(Convert(f.CourseId)).Equals("2")) Or StringConvert(Convert(f.CourseId)).Equals("1"))}
Dynamic Expression is
var param = Expression.Parameters(typeof(Course), "f")
MemberExpression property = Expression.PropertyOrField(param, "CourseId");
MethodInfo mi = null;
MethodCallExpression mce = null;
if (property.Type == typeof(int))
{
var castProperty = Expression.Convert(property, typeof(double?));
var t = Expression.Parameter(typeof(SqlFunctions), "SqlFunctions");
mi = typeof(SqlFunctions).GetMethod("StringConvert", new Type[] { typeof(double?) });
mce = Expression.Call(null,mi, castProperty);
}
mi = typeof(string).GetMethod("Equals", new Type[]{ typeof(string)});
BinaryExpression bex = null;
if (values.Length <= 1)
{
return Expression.Lambda<Func<T, bool>>(Expression.Call(mce, mi, Expression.Constant(values[0]), param));
}
//var exp1 = Expression.Call(mce, mi, Expression.Constant(values[0]));
for (int i = 0; i < values.Length; i++)
{
if (bex == null)
{
bex = Expression.Or(Expression.Call(mce, mi, Expression.Constant(values[i])), Expression.Call(mce, mi, Expression.Constant(values[i + 1])));
i++;
}
else
bex = Expression.Or(bex, Expression.Call(mce, mi, Expression.Constant(values[i])));
}//End of for loop
return Expression.Lambda<Func<T, bool>>(bex, param);
2) The 2nd way that i tried (debug view)
{f => val.Contains("23")} //val is parameter of values above
The dynamic expression for above that i tried is
var param = Expression.Parameters(typeof(Course), "f")
MemberExpression property = Expression.PropertyOrField(param, "CourseId");
var micontain = typeof(Enumerable).GetMethods().Where(m => m.Name == "Contains" && m.GetParameters().Length == 2).Single().MakeGenericMethod(typeof(string));
var mc = Expression.Call(micontain, Expression.Parameter(values.GetType(), "val"), Expression.Constant("2"));//NOTE: I haven't use CourseId for now as i am getting conversion error
return Expression.Lambda<Func<T, bool>>(mc, param);
I get the following errors
LINQ to Entities does not recognize the method 'System.String StringConvert(System.Nullable`1[System.Double])' method, and this
method cannot be translated into a store expression when i use the
first methodology. I know i can't use ToString with EF thats why I used SqlFunctions but it is not working for me.
The parameter 'val' was not bound in the specified LINQ to Entities query expression using 2nd methodology
I am trying this from last 4 days. I googled it but didn't find any suitable solution. Please help me.
After a lot of struggle I found solution to my question.
I want to achieve this sql query
select * from Courses where CourseId in (1, 2, 3, 4)
Using Linq to Entities, but I want to pass in(1,2,3,4) list dynamically to linq query. I created an Extension class for that purpose.
public static class LinqExtensions
{
public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<Func<T, bool>> In<T, TValue>(this Expression<Func<T, bool>> predicate,string propertyName, List<TValue> values)
{
var param = predicate.Parameters.Single();
MemberExpression property = Expression.PropertyOrField(param, propertyName);
var micontain = typeof(List<TValue>).GetMethod("Contains");
var mc = Expression.Call(Expression.Constant(values), micontain, property);
return Expression.Lambda<Func<T, bool>>(mc, param);
}
}
Use of LinqExtensions
var pred = LinqExtensions.False<Course>(); //You can chain In function like LinqExtensions.False<Course>().In<Course, int>("CourseId", inList);
var inList= new List<int>(){1, 2, 3}; //Keep in mind the list must be of same type of the Property that will be compared with. In my case CourseId is integer so the in List have integer values
pred =pred.In<Course, int>("CourseId", inList); //TValue is int. As CourseId is of type int.
var data = MyEntities.Courses.Where(pred);
I hope this might be beneficial for some one
have you seen the type of
var courselist = DBEntities.Courses.Where(c => ids.Contains(c.CourseId)))
above statement would not return actual list of courses. The query is not executed yet. It just returns IQuereable. The query is executed when you actually call .ToList() method on it
so, your solution is..
Create array of IDs using for loop and then simply run the below query
var courselist = DBEntities.Courses.Where(c => ids.Contains(c.CourseId))).ToList()

where can I find a good example of using linq & lambda expressions to generate dynamic where and orderby sql?

where can I find a good example of using linq & lambda expressions to generate dynamic sql?
For example, I need a method to take these parameters
GoupOperator ('And' or 'OR')
A list of objects each with the following parameters:
SearchColumn.
SearchValue.
SearchOperator (equals, contains, does not equal ...)
And another method to orderby any particular column ascending or descending
If this question has been properly answered before , I will gladly delete it - none of previous answers Ive seen are comprehensive enough for a person new to linq expressions to plug into an existing application with little trouble --thanks
I found a couple of linq extension methods (generic Where and OrderBy methods written by Ilya Builuk that take the columnname, search value and search operations plus a grouping operator) on codeproject here that shows how to do this using asp.net mvc.
the methods construct a dynamic expression tree -very elegant solution.
Since I had started using a traditional asmx web service, I used his helpers in my project and just made a few changes to get it running here -
Here are the 2 methods
public static class LinqExtensions
{
/// <summary>Orders the sequence by specific column and direction.</summary>
/// <param name="query">The query.</param>
/// <param name="sortColumn">The sort column.</param>
/// <param name="ascending">if set to true [ascending].</param>
public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string sortColumn, string direction)
{
string methodName = string.Format("OrderBy{0}",
direction.ToLower() == "asc" ? "" : "descending");
ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
MemberExpression memberAccess = null;
foreach (var property in sortColumn.Split('.'))
memberAccess = MemberExpression.Property
(memberAccess ?? (parameter as Expression), property);
LambdaExpression orderByLambda = Expression.Lambda(memberAccess, parameter);
MethodCallExpression result = Expression.Call(
typeof(Queryable),
methodName,
new[] { query.ElementType, memberAccess.Type },
query.Expression,
Expression.Quote(orderByLambda));
return query.Provider.CreateQuery<T>(result);
}
public static IQueryable<T> Where<T>(this IQueryable<T> query,
string column, object value, WhereOperation operation)
{
if (string.IsNullOrEmpty(column))
return query;
ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
MemberExpression memberAccess = null;
foreach (var property in column.Split('.'))
memberAccess = MemberExpression.Property
(memberAccess ?? (parameter as Expression), property);
//change param value type
//necessary to getting bool from string
ConstantExpression filter = Expression.Constant
(
Convert.ChangeType(value, memberAccess.Type)
);
//switch operation
Expression condition = null;
LambdaExpression lambda = null;
switch (operation)
{
//equal ==
case WhereOperation.Equal:
condition = Expression.Equal(memberAccess, filter);
lambda = Expression.Lambda(condition, parameter);
break;
//not equal !=
case WhereOperation.NotEqual:
condition = Expression.NotEqual(memberAccess, filter);
lambda = Expression.Lambda(condition, parameter);
break;
//string.Contains()
case WhereOperation.Contains:
condition = Expression.Call(memberAccess,
typeof(string).GetMethod("Contains"),
Expression.Constant(value));
lambda = Expression.Lambda(condition, parameter);
break;
}
MethodCallExpression result = Expression.Call(
typeof(Queryable), "Where",
new[] { query.ElementType },
query.Expression,
lambda);
return query.Provider.CreateQuery<T>(result);
}
}
Below is how I used these methods, the return object is simply a custom object that supplies data to a client side grid
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public JgGrid SearchGrid(int rows, int page, string sidx, string sord,string filters)
{
AdvWorksDataContext dc = new AdvWorksDataContext();
JavaScriptSerializer serializer = new JavaScriptSerializer();
filters f = serializer.Deserialize<filters>(filters);
var p = dc.vProductAndDescriptions.AsQueryable();
if (f.groupOp == "AND")
foreach (var rule in f.rules)
p = p.Where<vProductAndDescription>(
rule.field, rule.data,
(WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op)
);
else
{
//Or
var temp = (new List<vProductAndDescription>()).AsQueryable();
foreach (var rule in f.rules)
{
var t = p.Where<vProductAndDescription>(
rule.field, rule.data,
(WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op)
);
temp = temp.Concat<vProductAndDescription>(t);
}
p = temp;
}
p = p.OrderBy<vProductAndDescription>(sidx, sord);
return new JgGrid(page, p, rows);
}
}
For cases where I have many columns that need dynamic query composition I use Dynamic Linq. This is a library written as an example for .net 3.5 and it illustrates how you can write linq extensions that operate on the expression tree.
It can also be used for composing dynamic queries based on strings received from the client, such as column names, sorting, etc.
Here's a link a to an article posted by Scott Guthrie
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
In the article you will find the links to the examples library which contains the source code for the Dynamic Linq library.
It seems to me that you're trying to build a linq provider...
Try to check this tutorial serie on how to implement a custom Linq to SQL provider : LINQ: Building an IQueryable provider series

Categories

Resources