Dynamic Where Linq to Entities

c# dynamic dynamic-linq linq linq-to-entities

Question

I've been looking at the best ways to create dynamic Linq searches. I'm building a web application interface that will let users choose attributes from a database and provide where clauses to produce reports dynamically. All of the queries I've seen in stack overflow or other websites mention using LinqKit and Dynamic Linq to solve the issue, for instance Here. But I'm having trouble coming up with a way to represent 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");

In Linq to Entities, I hope to do something similar. I don't want to extract all of the data and run Linq to Object since the database is too big, and Linq to Entities doesn't enable reflection in that way. Any advice on how to write this in Dynamic Linq would be appreciated. If you can convert the type to the property type such that it can be evaluated using common operators (==, >,, etc.), you will get bonus points.

1
2
10/10/2014 5:31:28 PM

Accepted Answer

Using Active Linq, modify your query as follows:

var propName = "CopyrightDate";
var propValue = "2006";
Model.Titles.Where(string.Format("{0}=@0", propName), propValue);

string.Format("{0}=@0", propName) creates the search string for theWhere condition, which would be"CopyrightDate=@0" this instance.@0 defines the query's argument, which becomespropValue .

0
10/10/2014 5:18:59 PM

Popular Answer

What the LINQ-to-entitiesWhere an extension approach is desiredExpression<Func<T, bool>> . You might construct the following expression:

// 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 your class's type, which includes theCopyrightDate property.

var result = context.Titles
    .Where(lambda)
    .ToList();

A little more broadly, the answer 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);
}


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow