簡體   English   中英

C#Generic Linq查詢

[英]C# Generic Linq Query

我需要寫一些通用的搜索方法,如下所示:

public List<T> Search<T>(SearchParamsBase searchParams)
{
    using (var context = new TestEntities())
    {
        var dataType = TypeMap.Get(typeof (T));
        var dataSet = context.Set(dataType);

        var searchQuery = CreateQuery((IEnumerable<object>) dataSet), searchParams)

        return searchQuery.ToList()
    }
}

我有一個函數CreateQuery() ,它應該過濾IEnumerable對象。 所有類別的此功能都不同。 例如:

CreateQuery(IEnumerable<object> collection, SearchParamsBase searchParams)
{
    var search = (SomeSearchImplementation)searchParams;
    // filter 
    collection = collection.Where(x => x.Name == search.Name);
    // select page
    collection = collection.Skip(search.Page * search.CountPerPage);
    collection = collection.Take(search.CountPerPage);
    // order by and so on
    // ...
    return collection;
}

我該如何正確實現這個想法?

你基本上想要做的是動態構造LINQ查詢。 為此,您需要在運行時修改/構建表達式樹。 如果您不熟悉表達式樹和Expression<T>類型,我推薦本文以及“另請參閱”部分中引用的頁面:

http://msdn.microsoft.com/en-us/library/bb397951.aspx

現在您已經掌握了基本概念,讓我們實現動態排序。 下面的方法是IQueryable<T>的擴展,這意味着它不僅適用於列表,而且適用於每個LINQ數據源,因此您也可以直接對數據庫使用它(在分頁和排序方面比在數據庫中更有效)記憶操作)。 該方法采用您要排序的屬性名稱和排序方向(升序/降序):

public static IQueryable<T> OrderByDynamic<T>(this IQueryable<T> query, string sortColumn, bool descending) 
{
    // Dynamically creates a call like this: query.OrderBy(p => p.SortColumn)
    var parameter = Expression.Parameter(typeof(T), "p");

    string command = "OrderBy";

    if (descending)
    {
        command = "OrderByDescending";
    }

    Expression resultExpression = null;    

    var property = typeof(T).GetProperty(sortColumn);
    // this is the part p.SortColumn
    var propertyAccess = Expression.MakeMemberAccess(parameter, property);

    // this is the part p => p.SortColumn
    var orderByExpression = Expression.Lambda(propertyAccess, parameter);

    // finally, call the "OrderBy" / "OrderByDescending" method with the order by lamba expression
    resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { typeof(T), property.PropertyType },
       query.Expression, Expression.Quote(orderByExpression));

    return query.Provider.CreateQuery<T>(resultExpression);
}

現在,您可以編寫此代碼,按屬性Name ascending對數據集進行排序:

dataSet.OrderByDynamic("Name", false)

為動態過濾創建擴展方法遵循相同的模式。 如果你理解上面的代碼,那對你來說就沒問題了。

暫無
暫無

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

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