Как я применяю OrderBy на IQueryable использование строкового имени столбца в рамках универсального дополнительного метода?

Ничего не видно. Страница пуста и белая.

Также известна как Белая страница смерти или Белый экран смерти . Это происходит, когда отчет об ошибках отключен, и произошла фатальная ошибка (часто синтаксическая ошибка).

Если вы включили протоколирование ошибок, вы найдете конкретное сообщение об ошибке в своем журнале ошибок. Обычно это будет в файле php_errors.log, либо в центральном месте (например, /var/log/apache2 во многих средах Linux), либо в самом каталоге самого скрипта (иногда используется в среде совместного размещения).

Иногда может быть более простым временно отображать ошибки. На белой странице отобразится сообщение об ошибке. Будьте осторожны, потому что эти ошибки видны всем, кто посещает веб-сайт.

Это легко сделать, добавив в начале скрипта следующий код PHP:

ini_set('display_errors', 1); error_reporting(~0);

Код включит отображение ошибок и установит отчетность на самый высокий уровень.

Поскольку во время выполнения ini_set() он не влияет на синтаксические ошибки синтаксиса. Эти ошибки появятся в журнале. Если вы хотите также отобразить их на выходе (например, в браузере), вам необходимо установить директиву display_startup_errors на true. Сделайте это либо в php.ini, либо в .htaccess или любом другом методе, который влияет на конфигурацию перед временем выполнения .

Вы можете использовать те же методы для установки параметра log_errors и error_log , чтобы выбрать ваше собственное место в файле журнала.

Если вы посмотрите в журнале или используете дисплей, вы получите гораздо лучшее сообщение об ошибке и строка кода, где ваш скрипт останавливается.

Похожие вопросы:

Связанные ошибки:

83
задан Dan Atkinson 24 May 2012 в 12:41
поделиться

5 ответов

Мы сделали что-то подобное (не 100% то же, но подобный) в LINQ к проекту SQL. Вот код:

public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string ordering, params object[] values) {
    var type = typeof(T);
    var property = type.GetProperty(ordering);
    var parameter = Expression.Parameter(type, "p");
    var propertyAccess = Expression.MakeMemberAccess(parameter, property);
    var orderByExp = Expression.Lambda(propertyAccess, parameter);
    MethodCallExpression resultExp = Expression.Call(typeof(Queryable), "OrderBy", new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExp));
    return source.Provider.CreateQuery<T>(resultExp);
}

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

Редактирование: Для порядка по убыванию, передайте в OrderByDescending вместо "OrderBy":

MethodCallExpression resultExp = Expression.Call(typeof(Queryable), "OrderByDescending", new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExp));
108
ответ дан Dan Atkinson 24 November 2019 в 08:50
поделиться

Я расширил Ваши функции для добавления поддержки Дочерних Свойств.

private static LambdaExpression GenerateSelector<TEntity>(String propertyName, out Type resultType) where TEntity : class
{
    // Create a parameter to pass into the Lambda expression (Entity => Entity.OrderByField).
    var parameter = Expression.Parameter(typeof(TEntity), "Entity");
    //  create the selector part, but support child properties
    PropertyInfo property;
    Expression propertyAccess;
    if (propertyName.Contains('.'))
    {
            // support to be sorted on child fields.
            String[] childProperties = propertyName.Split('.');
            property = typeof(TEntity).GetProperty(childProperties[0]);
            propertyAccess = Expression.MakeMemberAccess(parameter, property);
            for (int i = 1; i < childProperties.Length; i++)
            {
                    property = property.PropertyType.GetProperty(childProperties[i]);
                    propertyAccess = Expression.MakeMemberAccess(propertyAccess, property);
            }
    }
    else
    {
            property = typeof(TEntity).GetProperty(propertyName);
            propertyAccess = Expression.MakeMemberAccess(parameter, property);
    }
    resultType = property.PropertyType;                     
    // Create the order by expression.
    return Expression.Lambda(propertyAccess, parameter);
}

private static MethodCallExpression GenerateMethodCall<TEntity>(IQueryable<TEntity> source, string methodName, String fieldName) where TEntity : class
{
    Type type = typeof(TEntity);
    Type selectorResultType;
    LambdaExpression selector = GenerateSelector<TEntity>(fieldName, out selectorResultType);
    MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName,
                                    new Type[] { type, selectorResultType },
                                    source.Expression, Expression.Quote(selector));
    return resultExp;
}

можно использовать эти функции как:

GenerateMethodCall<TEntity>(source, "OrderByDescending", fieldName);
12
ответ дан Davy Landman 24 November 2019 в 08:50
поделиться

Кажется, что это является способом сделать это, теперь проверить что:

// ***** OrderBy(company => company) *****
// Create an expression tree that represents the expression
// 'whereCallExpression.OrderBy(company => company)'
MethodCallExpression orderByCallExpression = Expression.Call(
    typeof(Queryable),
    "OrderBy",
    new Type[] { queryableData.ElementType, queryableData.ElementType },
    whereCallExpression,
    Expression.Lambda<Func<string, string>>(pe, new ParameterExpression[] { pe }));
// ***** End OrderBy *****
6
ответ дан JTew 24 November 2019 в 08:50
поделиться

Вы также можете использовать Dynamic Linq

здесь. http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

C # скачать здесь http://msdn.microsoft.com/en-us/vcsharp/bb894665.aspx

Затем просто добавьте using Linq.Dynamic; и вы автоматически получаете 2 дополнительных метода расширения, которые можно использовать следующим образом

return query.OrderBy("StringColumnName");
29
ответ дан 24 November 2019 в 08:50
поделиться

Я использовал вашу идею для метод расширения для OrderBy. Но в случае «многие ко многим» я получаю ошибку. Например, у вас есть таблица Site, Customer и Customer_site. Для данного сайта я хочу отсортировать по имени клиента и в расширении OrderBy (когда я передаю «site.customer», где клиент - это свойство навигации), я получаю сообщение об ошибке в строке: propertyAccess = Expression.MakeMemberAccess (propertyAccess, property);

Это это то, что я использую (с некоторыми улучшениями :-)):

public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string orderByValues) where TEntity : class
{
  IQueryable<TEntity> returnValue = null;

  string orderPair = orderByValues.Trim().Split(',')[0];
  string command = orderPair.ToUpper().Contains("DESC") ? "OrderByDescending" : "OrderBy";

  var type = typeof(TEntity);
  var parameter = Expression.Parameter(type, "p");

  string propertyName = (orderPair.Split(' ')[0]).Trim();

  System.Reflection.PropertyInfo property;
  MemberExpression propertyAccess;

  if (propertyName.Contains('.'))
  {
    // support to be sorted on child fields. 
    String[] childProperties = propertyName.Split('.');
    property = typeof(TEntity).GetProperty(childProperties[0]);
    propertyAccess = Expression.MakeMemberAccess(parameter, property);

    for (int i = 1; i < childProperties.Length; i++)
    {
      Type t = property.PropertyType;
      if (!t.IsGenericType)
      {
        property = t.GetProperty(childProperties[i]);
      }
      else
      {
        property = t.GetGenericArguments().First().GetProperty(childProperties[i]);
      }

      propertyAccess = Expression.MakeMemberAccess(propertyAccess, property);
    }
  }
  else
  {
    property = type.GetProperty(propertyName);
    propertyAccess = Expression.MakeMemberAccess(parameter, property);
  }

  var orderByExpression = Expression.Lambda(propertyAccess, parameter);

  var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType },

  source.Expression, Expression.Quote(orderByExpression));

  returnValue = source.Provider.CreateQuery<TEntity>(resultExpression);

  if (orderByValues.Trim().Split(',').Count() > 1)
  {
    // remove first item
    string newSearchForWords = orderByValues.ToString().Remove(0, orderByValues.ToString().IndexOf(',') + 1);
    return source.OrderBy(newSearchForWords);
  }

  return returnValue;
}

С уважением

Слободан

8
ответ дан 24 November 2019 в 08:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: