7

我正在使用这里提到的模式 http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in- an-asp-net-mvc-应用程序

我正在使用下面的方法来查询 EF

public virtual IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = "")
    {
        IQueryable<TEntity> query = dbSet;

        if (filter != null)
        {
            query = query.Where(filter);
        }

        foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
        {
            return orderBy(query).ToList();
        }
        else
        {
            return query.ToList();
        }
    }

现在我想创建动态Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>表达式来订购我的数据。

我只知道字段名称为字符串,订单类型(升序、降序)为字符串(asc、desc)

4

3 回答 3

16

最后我可以写出我想要的方法。

 public static Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> GetOrderBy(string orderColumn, string orderType) {
            Type typeQueryable = typeof(IQueryable<TEntity>);
            ParameterExpression argQueryable = Expression.Parameter(typeQueryable, "p");
            var outerExpression = Expression.Lambda(argQueryable, argQueryable);
            string[] props = orderColumn.Split('.');
            IQueryable<TEntity> query = new List<TEntity>().AsQueryable<TEntity>();
            Type type = typeof(TEntity);
            ParameterExpression arg = Expression.Parameter(type, "x");

            Expression expr = arg;
            foreach(string prop in props) {
                PropertyInfo pi = type.GetProperty(prop, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
                expr = Expression.Property(expr, pi);
                type = pi.PropertyType;
            }
            LambdaExpression lambda = Expression.Lambda(expr, arg);
            string methodName = orderType == "asc" ? "OrderBy" : "OrderByDescending";

            MethodCallExpression resultExp =
                Expression.Call(typeof(Queryable), methodName, new Type[] { typeof(TEntity), type }, outerExpression.Body, Expression.Quote(lambda));
            var finalLambda = Expression.Lambda(resultExp, argQueryable);
            return (Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>)finalLambda.Compile();
        }

这个方法有两个参数,第一个是字段名,另一个是 asc 或 desc。方法的结果可以直接与 IQueryable 对象一起使用。

感谢您的帮助

于 2013-04-15T18:08:41.880 回答
6

这对聚会来说已经很晚了,但正确的答案位于https://stackoverflow.com/a/10935223/14275的另一个问题上

var students = repository.Get(x => x.FirstName = "Bob",q => q.OrderBy(s => s.LastName));
于 2016-04-11T22:01:33.040 回答
2

我不确定您到底想完成什么,但我已经更改了您的代码并添加了一些示例来演示它是如何工作的。

这是一个简单的控制台应用程序,其中包含 dummyText 作为列表。Queryable 方法可以根据需要使用过滤和排序表达式。我希望它有帮助

 class Program
{

    private List<string> _dummyText = new List<string>(){ "Arda",
        "Araba",
        "Antartika",
        "Balon"};

    static void Main(string[] args)
    {
        Program p = new Program();
        List<string> result = p.Get(s => s.StartsWith("A"), orderBy: q => q.OrderBy(d => d.Length)).ToList();

        Console.ReadLine();
    }


    public virtual IEnumerable<string> Get(
    Expression<Func<string, bool>> filter = null,
    Func<IQueryable<string>, IOrderedQueryable<string>> orderBy = null)
    {

        IQueryable<string> query = _dummyText.AsQueryable();

        if (filter != null)
        {
            query = query.Where(filter);
        }

        if (orderBy != null)
        {
            return orderBy(query).ToList();
        }
        else
        {
            return query.ToList();
        }



    }

}
于 2013-04-15T13:02:47.217 回答