6

In my base-repository class

i wrote this function to make possible to retrive a sorted data collection from the DB. T is a generic defined at Class level

public abstract class RepositoryBase<T> 
        where T : class

The code is this:

public IList<T> GetAll<TKey>(Expression<Func<T, bool>> whereCondition, Expression<Func<T, TKey>> sortCondition, bool sortDesc = false)
        {
            if (sortDesc)
                return this.ObjectSet.Where(whereCondition).OrderByDescending(sortCondition).ToList<T>();

            return this.ObjectSet.Where(whereCondition).OrderBy(sortCondition).ToList<T>() ;
        }

My goal was to introduce a generic sort parameter so that i could call the function in this way:

repo.GetAll (model=>model.field>0, model=>model.sortableField, true)

i mean that i could specify the sorting field directly via anonymous function and so using Intellisense...

Unfortunately this function doesn't work as the last code line generate errors at compile time.

I tried also to call:

repo.GetAll<Model> (model=>model.field>0, model=>model.sortableField, true)

but this don't work.

How should i write the function to meet my goal?

i'm working with EF 5, c#, .NET 4.5

Alex
  • 1,237
  • 3
  • 18
  • 29
  • 3
    And the compile-time error is...? (*Any* time you have an error, whether compile-time or execution-time, please include it in the question. Don't keep us guessing.) – Jon Skeet Feb 25 '13 at 10:15
  • I think it should be Func<...> not Expression> – Eli Algranti Feb 25 '13 at 10:17
  • I was totally screwed. My function was working good, but i called it with a wrong Where condition... Should i delete this question? Anyway @EliAlgranti , i copied the template of the where condition parameters from a .NET tutorial. Can you tell me the difference between Func<...> and Expression> and why Func<...> should work better? – Alex Feb 25 '13 at 10:35
  • Also, here i've just found a similar question, and here too they use Expression> http://stackoverflow.com/questions/3828591/help-with-generic-linq-orderby-lambda-expression?rq=1 – Alex Feb 25 '13 at 10:37

1 Answers1

3

You're using ObjectSet which implements IQueryable<T>. That is extended by methods on System.Linq.Queryable, which accept Expression<Func< parameters. It is correct to use those Expression parameters, as you intend for execution to occur in the database, not locally.

  • A Func is an anonymous delegate, a .net method.
  • An Expression is a tree, which may be compiled into a Func, or may be translated into Sql or something else.

You showed us a really abstract use of the method, but not an actual use of the method, or the compiler error. I suspect the error you may be making is confusing the two type parameters.

You said:

repo.GetAll<Model> (model=>model.field>0, model=>model.sortableField, true)

But this generic parameter for this method represents the type of sortableField. If sortableField isn't a Model - this is wrong.

Instead, you should be doing something like this:

Repository<Person> myRepo = new Repository<Person>();
myRepo.GetAll<DateTime>(p => p.Friends.Count() > 3, p => p.DateOfBirth, true);

If specifying the sort type breaks your intended pattern of usage, consider hiding that key by using an IOrderer: Store multi-type OrderBy expression as a property

Community
  • 1
  • 1
Amy B
  • 108,202
  • 21
  • 135
  • 185
  • Thanks much for the reply. In my last comments i just said that the code i wrote in the question seems to work good. The error was generated by the 'where condition'. Pratically model.field>0 was failin because field was a String... Anyway i thank you very much as you solved me another couple doubts... I will mark your as the accepted answer because it explain very well the Expression concept. – Alex Feb 25 '13 at 17:51