Динамическое выражение LINQ для сортировки свойств навигации - PullRequest
6 голосов
/ 24 февраля 2012

MVC3, Entity Framework 4.1 Сначала код):

public virtual IQueryable< ProgramMaster > GetQueryableSort(string sortField="", string sortDirection="")
   {
      IQueryable<ProgramMaster> query = _dbSet;
      ParameterExpression pe = Expression.Parameter(typeof(ProgramMaster), string.Empty);
      MemberExpression property = Expression.PropertyOrField(pe, sortField);
     //get a exception here if the sort field is of navigation property                            (University.UniversityName)
      LambdaExpression lambda = Expression.Lambda(property, pe);
      if (sortDirection == "ASC")
         orderbydir = "OrderBy";
      else
         orderbydir = "OrderByDescending";
         MethodCallExpression call = Expression.Call(typeof(Queryable),
         orderbydir, new Type[] { typeof(TEntity), property.Type }, query.Expression,  Expression.Quote(lambda));

      var returnquery = (IOrderedQueryable<ProgramMaster>)query.Provider.CreateQuery< ProgramMaster >(call);
      return returnquery;
    }

На странице отображается сетка с двумя столбцами Название программы и Название университета с использованием веб-сетки.Сортировка работает нормально для столбца Имя программы, однако происходит сбой при сортировке по имени университета, поскольку это свойство находится в UniversityMaster, а Expression.PropertyOrField выполняет поиск этого свойства в ProgramMaster.Вот исключение:

University.UniversityName 'не является членом типа' App.Core.Model.ProgramMaster

Мой вопрос заключается в том, как заставить эту работунавигационные свойства моего модельного класса.

Надеюсь, я смог объяснить сценарий.Любая помощь приветствуется.

Ответы [ 2 ]

1 голос
/ 03 марта 2017

Microsoft имеет класс DynamicQueryable, который можно использовать для динамического построения определенных частей запроса LINQ с использованием строк. При этом вы можете сказать myQuery.OrderBy ("University.UniversityName"), и он будет обрабатывать построение выражения. Эта же библиотека также поддерживает динамическое построение предложений SELECT и WHERE.

Вы можете найти копию исходного кода как часть отличного пакета EntityFramework.Extended от Loresoft. Файл Microsoft находится в https://github.com/loresoft/EntityFramework.Extended/blob/master/Source/EntityFramework.Extended/Dynamic/DynamicQueryable.cs

0 голосов
/ 24 марта 2013

Ну, это потому, что MemberExpression пытается вызвать члена с именем Univerty.UniversityName для параметра.Что вы хотите сделать, это вызвать элемент с именем Univerity для параметра, а затем вызвать UniversityName для этого параметра.По сути, вам нужно итеративно разрешить имена свойств.

public virtual IQueryable< ProgramMaster > GetQueryableSort(string sortField = "", string sortDirection = "")
{
    IQueryable<ProgramMaster> query = _dbSet;

    var propertyNames = sortField.Split(".");

    ParameterExpression pe = Expression.Parameter(typeof(ProgramMaster), string.Empty);
    Expression property = pe;
    foreach(var prop in propertyName)
    {
        property = Expression.PropertyOrField(property, prop);
    }

    LambdaExpression lambda = Expression.Lambda(property, pe);

    if (sortDirection == "ASC")
        orderbydir = "OrderBy";
    else
        orderbydir = "OrderByDescending";

    MethodCallExpression call = Expression.Call(
        typeof(Queryable),
        orderbydir, 
        new Type[] { typeof(TEntity), property.Type }, 
        query.Expression, 
        Expression.Quote(lambda));

    var returnquery = (IOrderedQueryable<ProgramMaster>)query.Provider.CreateQuery<ProgramMaster>(call);

    return returnquery;
}
...