动态linq orderby null错误[英] Dynamic Linq OrderBy null error

本文是小编为大家收集整理的关于动态linq orderby null错误的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在使用Dynamic Linq来订购结果集,具体取决于传递哪个列.当用户单击表列时,我正在使用它来订购表.

如果属性IM订购是一个null的类,代码掉落了,我希望能够动态订购字符串,但如果属性为类,则适合nulls.

.

这是system.linq.dynamic class im使用的代码.

public static IQueryable OrderBy(this IQueryable source, string ordering,
    params object[] values)
{
    if (source == null) { throw new ArgumentNullException("source"); }
    if (ordering == null) { throw new ArgumentNullException("ordering"); }

    ParameterExpression[] parameters = new ParameterExpression[1]
    {
        Expression.Parameter(source.ElementType, "")
    };

    IEnumerable<DynamicOrdering> enumerable = new ExpressionParser(
        parameters, ordering, values).ParseOrdering();

    Expression expression = source.Expression;
    string str1 = "OrderBy";
    string str2 = "OrderByDescending";

    foreach (DynamicOrdering dynamicOrdering in enumerable)
    {
        expression = (Expression) Expression.Call(typeof (Queryable),
            dynamicOrdering.Ascending ? str1 : str2, new Type[2]
        {
            source.ElementType,
            dynamicOrdering.Selector.Type
        }, new Expression[2]
        {
            expression,
            (Expression) Expression.Quote((Expression) Expression.Lambda(
                dynamicOrdering.Selector, parameters))
        });
        str1 = "ThenBy";
        str2 = "ThenByDescending";
    }
    return source.Provider.CreateQuery(expression);
}

并像这样称呼它

if (property.PropertyType == typeof(Sitecore.Data.Items.Item))
{
    orderByProperty = property.Name + ".Name";
}
else
{
    orderByProperty = property.Name;
}

return tableOrder == TableOrder.az
    ? projects.OrderBy(orderByProperty + " ascending").ToList()
    : projects.OrderBy(orderByProperty + " descending").ToList();

属性有时是一类,如果是这种情况,我希望能够通过类上的名称订购.以上代码有效,但是如果属性是类,则属于null.

我该如何按字段订购并在末尾进行空项目?

推荐答案

我找到了答案.用以下内容替换system.linq.dynamic.dynamicqueryable类中的OrderBy查询.它将处理为对象的属性中的nulls.

public static IQueryable OrderBy(this IQueryable source, string ordering,
    params object[] values)
{
    //This handles nulls in a complex object
    var orderingSplit = ordering.Split(new char[] {' '},
        StringSplitOptions.RemoveEmptyEntries);
    var sortField = orderingSplit[0];
    var splitted_sortField = sortField.Split(new char[] { '.' }, 
        StringSplitOptions.RemoveEmptyEntries);

    if (splitted_sortField.Length > 1)
    {
        sortField = "iif(" + splitted_sortField[0] + "==null,null," + sortField + ")";
    }
    ordering = orderingSplit.Length == 2
       ? sortField + " " + orderingSplit[1]
       : sortField;

    if (source == null) throw new ArgumentNullException("source");
    if (ordering == null) throw new ArgumentNullException("ordering");

    ParameterExpression[] parameters = new ParameterExpression[] {
        Expression.Parameter(source.ElementType, "") };
    ExpressionParser parser = new ExpressionParser(parameters, ordering, values);
    IEnumerable<DynamicOrdering> orderings = parser.ParseOrdering();
    Expression queryExpr = source.Expression;
    string methodAsc = "OrderBy";
    string methodDesc = "OrderByDescending";

    foreach (DynamicOrdering o in orderings)
    {
        queryExpr = Expression.Call(
            typeof(Queryable), o.Ascending ? methodAsc : methodDesc,
            new Type[] { source.ElementType, o.Selector.Type },
            queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters)));
        methodAsc = "ThenBy";
        methodDesc = "ThenByDescending";
    }
    return source.Provider.CreateQuery(queryExpr);
}

从此处获取代码并将其直接烘烤到动态LINQ函数中.

null参考异常中的null参考异常/p>

本文地址:https://www.itbaoku.cn/post/1557036.html

问题描述

I'm using dynamic Linq to order a result set depending on which column is passed in. I'm using this to order a table when a user clicks on a table column.

If the property im ordering on is a class which is null the code falls over, i want to be able to dynamically orderby a string but cater for nulls if the property is a class.

This is the code from the System.Linq.Dynamic class im using.

public static IQueryable OrderBy(this IQueryable source, string ordering,
    params object[] values)
{
    if (source == null) { throw new ArgumentNullException("source"); }
    if (ordering == null) { throw new ArgumentNullException("ordering"); }

    ParameterExpression[] parameters = new ParameterExpression[1]
    {
        Expression.Parameter(source.ElementType, "")
    };

    IEnumerable<DynamicOrdering> enumerable = new ExpressionParser(
        parameters, ordering, values).ParseOrdering();

    Expression expression = source.Expression;
    string str1 = "OrderBy";
    string str2 = "OrderByDescending";

    foreach (DynamicOrdering dynamicOrdering in enumerable)
    {
        expression = (Expression) Expression.Call(typeof (Queryable),
            dynamicOrdering.Ascending ? str1 : str2, new Type[2]
        {
            source.ElementType,
            dynamicOrdering.Selector.Type
        }, new Expression[2]
        {
            expression,
            (Expression) Expression.Quote((Expression) Expression.Lambda(
                dynamicOrdering.Selector, parameters))
        });
        str1 = "ThenBy";
        str2 = "ThenByDescending";
    }
    return source.Provider.CreateQuery(expression);
}

and calling it like this

if (property.PropertyType == typeof(Sitecore.Data.Items.Item))
{
    orderByProperty = property.Name + ".Name";
}
else
{
    orderByProperty = property.Name;
}

return tableOrder == TableOrder.az
    ? projects.OrderBy(orderByProperty + " ascending").ToList()
    : projects.OrderBy(orderByProperty + " descending").ToList();

the property is sometimes a class, if this is the case i want to be able to order it by a field called name on the class. The above code works but if the property is a class and null then it falls over.

How do I order by a field and have the null items at the end?

推荐答案

I've found the answer. Replace the OrderBy query in the System.Linq.Dynamic.DynamicQueryable class with the below. It will handle nulls in a property that is an object.

public static IQueryable OrderBy(this IQueryable source, string ordering,
    params object[] values)
{
    //This handles nulls in a complex object
    var orderingSplit = ordering.Split(new char[] {' '},
        StringSplitOptions.RemoveEmptyEntries);
    var sortField = orderingSplit[0];
    var splitted_sortField = sortField.Split(new char[] { '.' }, 
        StringSplitOptions.RemoveEmptyEntries);

    if (splitted_sortField.Length > 1)
    {
        sortField = "iif(" + splitted_sortField[0] + "==null,null," + sortField + ")";
    }
    ordering = orderingSplit.Length == 2
       ? sortField + " " + orderingSplit[1]
       : sortField;

    if (source == null) throw new ArgumentNullException("source");
    if (ordering == null) throw new ArgumentNullException("ordering");

    ParameterExpression[] parameters = new ParameterExpression[] {
        Expression.Parameter(source.ElementType, "") };
    ExpressionParser parser = new ExpressionParser(parameters, ordering, values);
    IEnumerable<DynamicOrdering> orderings = parser.ParseOrdering();
    Expression queryExpr = source.Expression;
    string methodAsc = "OrderBy";
    string methodDesc = "OrderByDescending";

    foreach (DynamicOrdering o in orderings)
    {
        queryExpr = Expression.Call(
            typeof(Queryable), o.Ascending ? methodAsc : methodDesc,
            new Type[] { source.ElementType, o.Selector.Type },
            queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters)));
        methodAsc = "ThenBy";
        methodDesc = "ThenByDescending";
    }
    return source.Provider.CreateQuery(queryExpr);
}

Taken the code from here and baked it directly into the Dynamic Linq function.

Null Reference Exception in a Dynamic LINQ Expression