簡體   English   中英

Linq-to-Entities動態排序

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

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