tags:

views:

133

answers:

3

I am using an interface I found, which has a method that takes a LINQ expression as a parameter. How would I implement this method to use the LINQ Expression? I can see it being very useful, but dont how to write the code to use it!!

Its a repository interface.

signature is...

IQueryable<T> Get(Expression<Func<T, bool>> criteria);
A: 

That is a predicate expression; something that indicates data to include.

So, to get a single record you could use:

int rowId = 123;
var row = foo.Get(x => x.Id == rowId).Single();

Or to get all data matching some condition you could use:

var allDeleted = foo.Get(x => x.IsDeleted).ToList();

Note that this should be composable, for more fun:

var today = from row in foo.Get(x => x.DateCreated > DateTime.Today)
            orderby row.Name
            select new {row.Id, row.Name};
Marc Gravell
Thx Mark, I'm OK with using the predicates, i just don't know how the write the method that accepts the predicate.Thx
SteveCl
+3  A: 

Sounds like you are looking for something like this:

List<T> myList = new List<T>();
...
public IQueryable<int> Get(Expression<Func<int, bool>> criteria)
{
    return myList.Where(criteria.Compile()).AsQueryable();
}

This passes your expression criteria to the linq-method Where. You can then call it like this:

foreach(var something in myClass.Get(o => o.someProperty == 10))
{
    ...
}

Of course, this is pretty stupid; it would be better to just implement IEnumerable<T>...

BlueRaja - Danny Pflughoeft
thanks, knew it would be something simple!!! :)
SteveCl
+3  A: 

IQueryable<T> has an .Where() overload that takes an Expression<Func<T>> parameter. When assuming that this is a Linq2Sql or Linq2Entities repository, something like this should work

class MyRepository
{
    ObjectContext context = // initialize somehow;


    public IQueryable<int> Get(Expression<Func<int, bool>> predicate)
    {
        return context.SomeObject.Where(predicate);
    }
}

If that's not the case, and you only have an enumerable, you can use AsQuerably() as the first step in the chain to convert it to IQuerably, giving you the option to use the expression based predicate:

public IQueryable<int> Get(Expression<Func<int, bool>> predicate)
{
    return mySimpleList.AsQuerable().Where(predicate);
}
Sander Rijken
Thanks, I gave the bounty to BlueRaja, just because it was the first answer...thanks though, its very helpful
SteveCl
I think (not 100% sure though) that the `.Compile` followed by `.AsQueryable` is far worse performance wise if you're using a database. With linq2sql or linq2entities I think it will fetch all and perform the predicate in C# rather than in SQL.
Sander Rijken