I am trying to build a lambda query using expression trees to make it universal for use throughout the application. I based my initial attempt on the code found here . I changed the code so that it performs a comparison to return 100 objects whose LastName is immediately before the search text, for example:
TEntity entity = entitySet.FirstOrDefault();
string searchName = entity.GetType().GetProperty("SearchName").ToString();
searchText = "Baker";
int records = 100;
IQueryable<TEntity> queryableData = entitySet.AsQueryable<TEntity>();
var param = Expression.Parameter(typeof(TEntity), searchName);
var body = Expression.LessThan(Expression.Call(
typeof(string),
"Compare",
null,
Expression.PropertyOrField(param, searchName),
Expression.Constant(searchText)),
Expression.Constant(0));
var lambda = Expression.Lambda<Func<TEntity, bool>>(body, param);
MethodCallExpression whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { typeof(TEntity) },
queryableData.Expression,
lambda);
var data = entitySet.AsQueryable<TEntity>().Provider.CreateQuery<TEntity>(whereCallExpression).Take(records);
In the above code, it returns 100 objects from the database that are immediately before my search tag, but they are incorrect objects because they are not ordered in essence. So, I need an OrderBy clause in my expression tree to get "Azure", Axel, Avis "etc.
I tried this:
MethodCallExpression orderByCallExpression = Expression.Call(
typeof(Queryable),
"OrderByDescending",
new Type[] { typeof(TEntity), typeof(TEntity) },
whereCallExpression,
Expression.Lambda<Func<TEntity, string>>(param, new ParameterExpression[] { param }));
var data = entitySet.AsQueryable<TEntity>().Provider.CreateQuery<TEntity>(orderByCallExpression).Take(records);
" " System.ArgumentException " System.Core.dll,
: MyEntity ' "System.String"
StackTrace:
System.Linq.Expressions.Expression.ValidateLambdaArgs( delegateType, Expression & body, ReadOnlyCollection`1)
System.Linq.Expressions.Expression.Lambda [TDelegate] ( , , Boolean tailCall, IEnumerable`1)
System.Linq.Expressions.Expression.Lambda [TDelegate] ( , Boolean tailCall, IEnumerable`1)
, :
Expression<Func<TEntity, string>> sortExp = l => l.SearchName);
MethodCallExpression orderByCallExpression = Expression.Call(
typeof(Queryable),
"OrderByDescending",
new Type[] { typeof(TEntity), typeof(string) },
whereCallExpression,
sortExp);
" " System.NotSupportedException " mscorlib.dll,
: member 'SearchName' LINQ to Entities. , . "
, , SearchName , , OrderBy. :
l => (string)l.GetType().GetProperty("SearchName").GetValue(SearchName);
: " " System.NotSupportedException " mscorlib.dll,
: LINQ to Entities 'System.Object GetValue (System.Object)', . "
TEntity EntityObject
SearchName - TEntity, .
entitySet ObjectSet<TEntity>
.
, . , SearchName:
var type = typeof(TEntity);
var property = type.GetProperty(searchName);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
MethodCallExpression orderByCallExpression = Expression.Call(
typeof(Queryable),
"OrderByDescending",
new Type[] { typeof(TEntity), typeof(string) },
whereCallExpression,
Expression.Quote(orderByExp));
var data = entitySet.AsQueryable<TEntity>().Provider.CreateQuery<TEntity>(orderByCallExpression).Take(records);