通用列表 [英] Generic List of OrderBy Lambda

查看:108
本文介绍了通用列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个通用查询机制来访问我的存储库。我想使用Lambda表达式来过滤和排序查询。我正在努力找到一种方法来传递一般的Lambda表达式列表,特别是为了顺序排列,并希望能够这样做。



编辑:2我想要满足的要求是,不会将IQueryable暴露在存储库之外,但仍然可以在数据库级别进行一些过滤和排序。



为了更好地说明这一点我向你显示代码

  public class Query< T> 
{
public class OrderBy< T>
{
public Expression< Func< T,** int **>>条款{set;得到; } // Order By子句
public bool Descending = true;
}

public Expression< Func< T,bool>>其中{set;得到; } // Where子句
public IList< OrderBy&T>> OrderBys {set;得到; } // where子句

public Query()
{
OrderBys = new List< OrderBy&T;>();
}
}

public IEnumerable< Person> FindBy(查询< Person>查询)
{
IQueryable< Person> Temp = GetObjectSet();
if(query.Where!= null)Temp = Temp.Where(query.Where);
foreach(var OrderByThis in query.OrderBys)
{
if(OrderByThis.Descending)Temp = Temp.OrderByDescending(OrderByThis.Clause);
else Temp = Temp.OrderBy(OrderByThis.Clause);
}

返回Temp.ToList< Person>();
}

这是非常好的,但表达式< FUNC< T, int >>不是通用的。我需要这样做:

 查询< Person> query = new Query< Person>(); 
查询< Person> .OrderBy< Person>子句1 =新查询< Person> .OrderBy< Person>();
clause1.Clause = m => m.Username;
查询< Person> .OrderBy< Person>子句2 =新查询< Person> .OrderBy< Person>();
clause2.Clause = m => m.DateOfBirth;
query.OrderBys.Add(clause1);
query.OrderBys.Add(clause2);

ie。添加不同类型的不同字段。



我想象必须有一种方式将这些字段存储为通用的Lambda函数,然后在存储库中转换为强



我该怎么做?

解决方案

p>正如我在您的其他问题的回答中所指出的,我一般会劝阻这种方法。只要公开 IQueryable< T> / IOrderedQueryable< T> 。 b

据说,在选择的答案中有一个解决方案可以在如何将多个表达式传递给EF的OrderBy?



它允许您使用语法如:

  var query = context.Users ...; 

var queryWithOrderBy = ApplyOrderBy(query,
new OrderByExpression< User,string>(expression:u => u.UserName,descending:false),//一个字符串,asc
new OrderByExpression< User,int>(expression:u => u.UserId,descending:true)); //一个int,desc

var result = queryWithOrderBy.ToList(); //没有为我抛出一个异常


I am trying to build a generic query mechanism to access my repository. I wish to use Lambda expressions to filter and sort the query. I am struggling to find a way to pass a list of generic Lambda expressions in, specifically for the order-by, and would appreciate help in doing so.

EDIT: 2 requirements I am trying to meet is, not expose IQueryable beyond the repository, but still be able to carry out some filtering and sorting at database level.

To better illustrate this let me show you the code

public class Query<T>
{
    public class OrderBy<T>
    {
        public Expression<Func<T, **int**>> Clause { set; get; } // Order By clause
        public bool Descending = true;
    }

    public Expression<Func<T, bool>> Where { set; get; } // Where clause
    public IList<OrderBy<T>> OrderBys { set; get; } // Where clause

    public Query()
    {
        OrderBys = new List<OrderBy<T>>();
    }
}    

    public IEnumerable<Person> FindBy(Query<Person> query)
    {
        IQueryable<Person> Temp = GetObjectSet();
        if (query.Where != null) Temp = Temp.Where(query.Where);
        foreach (var OrderByThis in query.OrderBys)
        {
            if (OrderByThis.Descending) Temp = Temp.OrderByDescending(OrderByThis.Clause);
            else Temp = Temp.OrderBy(OrderByThis.Clause);
        }

        return Temp.ToList<Person>();
    }

This is all very nice, BUT Expression< Func< T, int>> is not generic. I need to be able to do something like:

Query<Person> query = new Query<Person>();
Query<Person>.OrderBy<Person> clause1 = new Query<Person>.OrderBy<Person>();
clause1.Clause = m => m.Username;
Query<Person>.OrderBy<Person> clause2 = new Query<Person>.OrderBy<Person>();
clause2.Clause = m => m.DateOfBirth;
query.OrderBys.Add(clause1);
query.OrderBys.Add(clause2);

i.e. adding a number of different fields of different types.

I imagine there must be a way to store these as generic Lambda functions, and then in the repository convert then to the strongly typed Lambda function it needs.

How can I do this?

解决方案

As I noted in my answer to your other question, I would discourage this approach in general. It makes more sense just to expose IQueryable<T>/IOrderedQueryable<T>.

That being said, there is a solution along the lines of your intention available in the selected answer to How to pass multiple Expressions to OrderBy for EF? .

It allows you to use a syntax like:

var query = context.Users ... ;

var queryWithOrderBy = ApplyOrderBy(query,
    new OrderByExpression<User, string>(expression: u => u.UserName, descending: false),    // a string, asc
    new OrderByExpression<User, int>(expression: u => u.UserId, descending: true));  // an int, desc

var result = queryWithOrderBy.ToList(); // didn't throw an exception for me

这篇关于通用列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆