C#泛型LINQ查询 [英] C# Generic Linq Query

查看:216
本文介绍了C#泛型LINQ查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要写一些像这样的通用搜索方式:

I need to write some generic Search Method like this:

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 对象。
,此功能将成为所有不同班。例如:

and I have a function CreateQuery() that should filter IEnumerable object. This function will be different for all classes. For example:

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



我怎样才能正确地实现这个想法?

How can I implement this idea correctly?

推荐答案

你想要做这里bascically动态构建LINQ查询什么。要做到这一点,你需要修改/在运行时构建表达式树。如果你不熟悉表达式树和表达式来; T> 键入我推荐这篇文章和另请参阅一节中引用的网页:

What you want to do here is bascically constructing a LINQ query dynamically. To do this, you need to modify/build the expression tree at runtime. If you are not familiar with expression trees and the Expression<T> type I recommend this article and the referenced pages in the "See also" section:

http://msdn.microsoft.com/ EN-US /库/ bb397951.aspx

现在,你现在的基本概念,让我们实现动态排序。下面的方法是一个扩展到的IQueryable< T> 这意味着它不仅适用于名单,但每一个LINQ数据源,所以你也可以直接使用它针对数据库(这是更有效的,当涉及到寻呼和比内存操作排序)。该方法需要你想订购属性名称和排序方向(升序/降序):

Now that you now the basic concept, let's implement dynamic sorting. The method below is an extension to IQueryable<T> which means it does not only apply to lists but to every LINQ datasource, so you could also use it directly against a database (which is more efficient when it comes to paging and sorting than in memory operations). The method takes the property name you want to order by and the sort direction (ascending/descending):

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

现在,你可以这样写代码,命令由物业数据集名称命令:

Now you can write this code to order the dataset by the property Name in ascending order:

dataSet.OrderByDynamic("Name", false)

创建动态过滤的扩展方法如下相同的模式。如果你理解了上面的代码,它不会成为你的问题。

Creating an extension methods for dynamic filtering follows the same pattern. If you understand the code above, it won't be a problem for you.

这篇关于C#泛型LINQ查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆