[英]Linq-to-Entities Dynamic sorting
這是我的查詢,如何使用string作為orderby參數?
string sortColumn="Title";
var items = (from ltem in ctxModel.Items
where ltem.ItemID == vId
orderby //something here
select ltem).Skip(PageSize * PageIndex).Take(PageSize);
更新:
我不能只是排序依據的結果集,因為我首先需要進行排序, 然后才是頁。
我用這個助手:
public static class OrderExt
{
private static IOrderedQueryable<T> Order<T>(this IQueryable<T> source, string propertyName, SortDirection descending, bool anotherLevel = false)
{
var param = Expression.Parameter(typeof(T), string.Empty);
var property = Expression.PropertyOrField(param, propertyName);
var sort = Expression.Lambda(property, param);
var call = Expression.Call(
typeof (Queryable),
(!anotherLevel ? "OrderBy" : "ThenBy") +
(descending == SortDirection.Descending ? "Descending" : string.Empty),
new[] {typeof (T), property.Type},
source.Expression,
Expression.Quote(sort));
return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(call);
}
}
調用助手,例如:
string sort = HttpContext.Current.Request.QueryString["sort"];
var products = _productRepository.OrderBy(sort, SortDirection.Ascending);
這是另一種選擇, EntitySorter 。 允許動態LINQ對字符串執行的操作,但將操作包裝在對象中,就像使用查詢對象模式一樣 。 它允許按字符串排序和類型安全構造。 這里有些例子:
// Ways of defining an entity sorter
// 1. Using strings:
IEntitySorter<Person> sorter = EntitySorter<Person>
.OrderBy("Address.City")
.ThenByDescending("Id");
// 2. Defining a sorter with lambda's
IEntitySorter<Person> sorter = EntitySorter<Person>
.OrderByDescending(p => p.Name)
.ThenBy(p => p.Id)
.ThenByDescending(p => p.Address.City);
// 3. Using a LINQ query
IEntitySorter<Person> sorter =
from person in EntitySorter<Person>.AsQueryable()
orderby person.Name descending, person.Address.City
select person;
// And you can pass a sorter from your presentation layer
// to your business layer, and you business layer may look
// like this:
static Person[] GetAllPersons(IEntitySorter<Person> sorter)
{
using (var db = ContextFactory.CreateContext())
{
IOrderedQueryable<Person> sortedList =
sorter.Sort(db.Persons);
return sortedList.ToArray();
}
}
你可以在這里找到代碼。
其他人建議使用動態鏈接或其他庫。 就個人而言 ,我不會為這么小的任務帶來庫依賴。 但你可以采取另外兩條路徑......
見http://blog.cincura.net/229310-sorting-in-iqueryable-using-string-as-column-name/
在此方案中考慮延遲執行很重要。 您可以安全地構建返回IQueryable對象的查詢,然后對該對象運行對象查詢排序。 只有在實際訪問數據時,您的查詢才會運行一次。
上面的博客文章是一個示例,說明如何使用Expression API構建和表達樹,您可以將其用於OrderBy 。 這聽起來真的很復雜。 MSDN文章可能是更好的參考。 請參見如何:使用表達式樹在MSDN上構建動態查詢 。
要么
例如。
ItemType items = default(ItemType);
switch(sortColumn)
{
case "Title":
{
items = ctxModel.Items
.Where(i => i.ItemID == vId)
.OrderBy( i => i.Title);
}
break;
}
顯然, Dynamic Linq的其他暗示還不夠明確。 讓我說清楚..
使用Dynamic Linq並不一定表示需要匯編依賴。
動態Linq包含在一個源文件中,如果我沒有記錯的話,它包含在C#示例中,每個人都應該至少在過去3年的某個時間看過,並且很容易被放入項目和命名空間以防止沖突,從而提供可在需要時使用的表達式構建服務。
我認為能夠從一個合理的任意string
安全地構造一個表達式,這個string
可以很容易地動態構建,成為“動態”的最好例子。
考慮:
var query = northwind.Products
.Where("CategoryID = 3 AND UnitPrice > 3")
.OrderBy("SupplierID");
該查詢看起來像是在使用自定義數據綁定和/或ObjectDataSource,無論如何,有一種方法可以使用擴展方法來執行此操作,該方法采用排序表達式並動態地將orderBy()調用(表達式)附加到linq查詢。 我記錄了博客在一段時間后發布的內容,巧合的是這個問題的一部分。 如果你需要更多,你可以使用scottgu 很好地記錄的 動態linq 。
編輯:使用擴展方法會使它看起來像
string sortColumn="Title";
var items = (from ltem in ctxModel.Items
where ltem.ItemID == vId
select ltem).Skip(PageSize * PageIndex).Take(PageSize).OrderBy(sortColumn);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.