[英]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.