簡體   English   中英

OrderBy Lambda的通用列表

[英]Generic List of OrderBy Lambda

我正在嘗試構建一個通用的查詢機制來訪問我的存儲庫。 我希望使用Lambda表達式來過濾和排序查詢。 我正在努力尋找一種方法來傳遞一般的Lambda表達式列表,特別是對於order-by,並且非常感謝這樣做的幫助。

編輯:我想要滿足的2個要求是,不要將IQueryable暴露在存儲庫之外,但仍然能夠在數據庫級別執行一些過濾和排序。

為了更好地說明這一點,讓我告訴你代碼

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>();
}

這一切都非常好,但Expression <Func <T, int >>不是通用的。 我需要能夠做到這樣的事情:

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);

即添加許多不同類型的不同字段。

我想必須有一種方法將這些存儲為通用Lambda函數,然后在存儲庫中轉換為它需要的強類型Lambda函數。

我怎樣才能做到這一點?

詳細說明我的評論,我不明白為什么你需要從Expressions中構建自己的中間查詢對象,然后從那個中間對象重構表達式,當你完全跳過那個翻譯時。

給出您的示例查詢:

repository.FindBy(people => people.OrderBy(p => p.Username).ThenBy(p => p.DateOfBirth));

請注意,例如,如果基於用戶選擇完成查詢,您仍然可以逐步構建查詢。 以下查詢等同於以上內容:

Func<IEnumerable<Person>, IEnumerable<Person>> query = people => people.OrderBy(p => p.Username);
 query = query.ThenBy(p => p.DateOfBirth);

我知道您不希望將IQueryable暴露在存儲庫之外,但您仍然可以使用帶有簽名的LINQ,例如:

public IEnumerable<Person> FindBy(Func<IEnumerable<Person>, IEnumerable<Person>> query)
{
    return query(GetObjectSet()).ToList();
}

但是,根據您的實際問題,您可以通過對Clause屬性類型使用Expression<Func<T, object>>來實現OrderBy任務,或者如果這讓您感到不安,則可以通過使用IComparable而不是對象來約束它,因為它實際上是您需要的所有訂購,字符串和數字類型都實現它。

正如我在回答你的另一個問題時所指出的那樣,我總體上不鼓勵這種做法。 公開IQueryable<T> / IOrderedQueryable<T>更有意義。

話雖如此,在如何將多個表達式傳遞給OrderBy for EF的選定答案中,可以找到與您的意圖相符的解決方案嗎?

它允許您使用如下語法:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM