Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Generic Linq Query

Tags:

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

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?

like image 916
bogdan Avatar asked Apr 10 '13 11:04

bogdan


People also ask

What is C in simple words?

C Introduction C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

Is C or C++ same?

While C and C++ may sound similar, their features and usage differ. C is a procedural programming language that support objects and classes. On the other hand C++ is an enhanced version of C programming with object-oriented programming support.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.


1 Answers

What you basically want to do here is construct 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/library/bb397951.aspx

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 method for dynamic filtering follows the same pattern. If you understand the code above, it won't be a problem for you.

like image 108
Markus Palme Avatar answered Oct 04 '22 07:10

Markus Palme