CallExpression orderby method

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);
+4
3

, SearchName, .

                 if (entity.SearchName == "LastFirstName")
                {
                    //// Construct Expressions to hold the propert values
                    Expression lastNameExp = Expression.PropertyOrField(param, "LastName");
                    Expression firstNameExp = Expression.PropertyOrField(param, "FirstName");

                    //// Construct a String.Concat method. 
                    MethodInfo methodInfo = typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) });

                    //// Combine the LastName + FirstName for the compare
                    MethodCallExpression combinedExp = Expression.Call(methodInfo, lastNameExp, firstNameExp);
0

SearchName - , , , [ignore] this.Ignore(t => t.Property);.

0

,

l => l.GetPropertyValue(l.SearchName) == "MyString"

GetPropertyValue , SearchString. , , EF SQL. SQL . .

. , :

l =>
  (
   l.SearchName == "MyField1" ? l.MyField1 :
   l.SearchName == "MyField2" ? 2.MyField1 :
   l.SearchName == "MyField3" ? 3.MyField1 :
   null
  ) == "MyString"

l =>
   l.SearchName == "MyField1" && l.MyField1 == "MyString" ||
   l.SearchName == "MyField2" && l.MyField2 == "MyString" ||
   l.SearchName == "MyField3" && l.MyField3 == "MyString" ||
   false
0

Source: https://habr.com/ru/post/1543267/


All Articles