-1

I have a class that works as a repository of some sort, and grants access to a database. I'm trying to customize it to allow queries with expressions.

So, I want to be able to do this:

IList<MyClass> myList = myRepository.GetBy(x => x.Name == "SomeName");
//and...
IList<MyClass> myList2 = myRepository.GetBy(x => x.Name == "SomeName" && x.ID = 5);

This is what I need to have on the repository function:

public IList<T> GetBy(Expression<Func<T, bool>> expression)
{
    //Set up the query, etc
    //I'm at the WHERE clause, and I need to get the property(ies) name(s) of the expression and their values to properly set the WHERE
}

How can I do this?

user2864740
  • 60,010
  • 15
  • 145
  • 220
Danicco
  • 1,573
  • 2
  • 23
  • 49
  • 4
    http://msdn.microsoft.com/en-us/library/bb882521(v=vs.90).aspx – MarcinJuraszek Oct 18 '14 at 01:26
  • What is stopping you doing `blah.Where(expression.Compile())`? – DavidG Oct 18 '14 at 02:17
  • @DavidG It will be inefficient. `Compile` returns delegate, so prediction will be applied at server side - after fetching all objects from database. It would ask why don't use just `queryable.Where(expression);` –  Oct 18 '14 at 05:48
  • @pwas it will work, but I forgot OP was starting with IQueryable so the compile isn't needed :) – DavidG Oct 18 '14 at 12:03

2 Answers2

1

What you want to do is this: IList <MyClass> myList2 = myRepository.GetBy (x => x.Name == "SomeName" && x.ID = 5); It is true that you can represent x => x.Name == "SomeName" && x.ID = 5 with Expression <Func <T, bool >>

but also what you can do with the delegate Func <T, bool> only.

Regardless of which were to take the data will always be from an IEnumerable <T> so you always will have the Where method (whenever you use the namespace System.Linq), which accepts as a parameter a delegate Func <T, bool> . If the object IEnumerable <T> is a DbSet <T>, this will take care of transforming the delegate Func <T, bool> in a sql query. Remember that a Linq query, which is what is being used, is only executed when the query data is used or agrees with methods ToList () or ToArray () for example.

example: IEnumerable <MyClass> list = ... from wherever you get the data even from DbSet of EntityFramework

var query = list.Where (x => x.Name == "SomeName" && x.ID = 5);

query is a shost a query, it contains no data until this is done

foreach (var x in list) is being consumed, so the query is executed
{
   var c = x.Name;
}

or this

`var temp = query.ToList ();` 

This force to stored in a List <MyClass> With all this I want to say that if you use the DbSet of EntityFramework, what happens is that the delegate Func <T, bool> is transformed into a sql query, so that the data manager is responsible for filtering data (as it should be).  From this alone you would have to simply have your method

public IList <T> GetBy (Func <T, bool> expression)
{
    origen.Where (expression).ToList();
}
Hector Davila
  • 180
  • 2
  • 10
-1

if I understand your question correctly, you shoul inherit you repository interfaces from base generic repository interface.

public interface IRepositoryBase<TEntity>
{
    IList<TEntity> GetBy(Expression<Func<TEntity, bool>> expression)
}

and repository realisation from base repository implementation

public abstract class RepositoryBase<TEntity>: IRepositoryBase<TEntity>
{
    public MyEntities EntitiesContext { get; set; }

    public IList<TEntity> GetBy(Expression<Func<TEntity, bool>> expression)
    {
       return EntitiesContext.Set<TEntity>().Where(filter).ToList()
    }
}
  • If he already has a query provider then he doesn't need to do *anything*. The whole point of this question is that he doesn't have a query provider for the data source in question. – Servy Oct 29 '14 at 15:50