C#/.NET Core应用程序开发中使用Entity Framework根据实体属性名称字符串对查询动态排序

Entity Framework 作者: Rector 36 阅读 0 评论 0 收藏 收藏本文

郑重申明:本文未经许可,禁止任何形式转载

在.NET/.NET Core的应用程序开发过程中,使用Entity Framework进行数据持久化或者查询是很多.NET开发者的选择,Entity Framework为我们封装了实体和数据表之间的映射,也提供了非常丰富的接口,.NET开发人员可以方便,快速地完成一个查询和排序操作。比如根据实体属性进行排序:

query.OrderBy(x=>x.Property);

但在实际开发中,很多情况下我们的排序字段和排序方向都是动态地,这种情况下我们再按以上的排序方式实现,就得写条件来判断了,如:

if(field=="firstName")
{
    query.OrderBy(x=>x.FirstName);
}
else if(field=="lastName")
{
    query.OrderBy(x=>x.LastName);
}
...

这种实现方式从结果上来说是可以的,但从实现过程上是很老火的。假如有100种情况,我们得写100个判断吗?

显然,作为开发者是不允许这种情况发生的,本文就为大家分享如何根据实体属性名称实现动态Entity Framework查询排序的。

首先,创建一个静态扩展方法如下:

using System.Linq;
using System.Linq.Expressions;
using System;

namespace SomeNameSpace
{
    public static class SomeExtensionClass
    {
        public static IQueryable<T> OrderByField<T>(this IQueryable<T> q, string SortField, bool Ascending)
        {
            var param = Expression.Parameter(typeof(T), "p");
            var prop = Expression.Property(param, SortField);
            var exp = Expression.Lambda(prop, param);
            string method = Ascending ? "OrderBy" : "OrderByDescending";
            Type[] types = new Type[] { q.ElementType, exp.Body.Type };
            var mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
            return q.Provider.CreateQuery<T>(mce);
        }
    }
}

调用示例:

query  =  query.OrderByField(sortcriteria, true);

如果要让这个扩展支持ThenBy()这样的方法,则再对以上静态类进行扩展,如下:

public static class SomeExtensionClass
{
    private static IOrderedQueryable<T> OrderingHelper<T>(IQueryable<T> source, string propertyName, bool descending, bool anotherLevel)
    {
        var param = Expression.Parameter(typeof(T), "p");
        var property = Expression.PropertyOrField(param, propertyName);
        var sort = Expression.Lambda(property, param);

        var call = Expression.Call(
            typeof(Queryable),
            (!anotherLevel ? "OrderBy" : "ThenBy") + (descending ? "Descending" : string.Empty),
            new[] { typeof(T), property.Type },
            source.Expression,
            Expression.Quote(sort));

        return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(call);
    }

    public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName)
    {
        return OrderingHelper(source, propertyName, false, false);
    }

    public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName, bool descending)
    {
        return OrderingHelper(source, propertyName, descending, false);
    }

    public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string propertyName)
    {
        return OrderingHelper(source, propertyName, false, true);
    }

    public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string propertyName, bool descending)
    {
        return OrderingHelper(source, propertyName, descending, true);
    }
}

参考链接: https://stackoverflow.com/questions/16013807/unable-to-sort-with-property-name-in-linq-orderby/22227975

阅读了该文章的人还浏览了...

本文永久链接码友网 » C#/.NET Core应用程序开发中使用Entity Framework根据实体属性名称字符串对查询动态排序

发布于: 2019-03-29 16:13:55
分享扩散:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册