Reputation: 20995
I've been doing research on how to dynamically make queries for linq. I'm creating a UI for a web application which allows them to select properties from a DB and set where clauses to build reports dynamically. All of the questions I've seen on stack or other sites reference using Dynamic Linq and LinqKit to Solve the problem, example Here . However I can't find an solution to express the syntax.
// This attempts to grab out a title whose from the Database whose
// Copyright Date equals 2006
propName = "CopyrightDate";
Model.Titles.Where(t => t.GetType().GetProperty(propName).GetValue(t, null) == "2006");
I want to do something like this but in Linq to Entities. Linq to entities doesn't support reflection like that, I do not want to pull out all of the data and run Linq to Object the DB is too Large. Any Suggestions on how to write this in Dynamic Linq. Bonus points if you can cast the type to the property type so It can be evaultuated with standard operators (== , > , < , etc..).
Upvotes: 2
Views: 2714
Reputation: 112352
What the LINQ-to-entities Where
extension method wants, is an Expression<Func<T, bool>>
. You can create such an expression like this:
// Create lambda expression: t => t.CopyrightDate == "2006"
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
var lambda = Expression.Lambda<Func<T, bool>>(
Expression.Equal(
Expression.Property(parameter, "CopyrightDate"),
Expression.Constant("2006")
),
parameter
);
where T
is the type of your class containing the CopyrightDate
property.
var result = context.Titles
.Where(lambda)
.ToList();
A somewhat more general solution is:
Expression<Func<T, bool>> Comparison<T>(ExpressionType comparisonType,
string propertyName, object compareTo)
{
ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
MemberExpression property = Expression.Property(parameter, propertyName);
ConstantExpression constant = Expression.Constant(compareTo);
Expression body = Expression.MakeBinary(comparisonType, property, constant);
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
Upvotes: 4
Reputation: 726579
Here is how you can rewrite your query using Dynamic Linq:
var propName = "CopyrightDate";
var propValue = "2006";
Model.Titles.Where(string.Format("{0}=@0", propName), propValue);
string.Format("{0}=@0", propName)
produces the query string for the Where
clause, which would be "CopyrightDate=@0"
in this case. @0
specifies the parameter for the query, which becomes propValue
.
Upvotes: 0