Question

I am having a problem getting a reuasable lambda expression working with the AutoMapper Project().To extension method. I am using AutoMapper 3.1.1.

I want to be able to reuse a lambda expression by defining it as a variable, but am having issues getting this to work with the extension method.

Note the code and lambda expression shown below are simplified, my lambda expression is very complicated and I want to reuse it in a number of places.

Here is a lambda expression to reuse:

Func<Product, bool> myLambda = x => (x.Season.Id == 3);

Code Block 1 uses Project().To<> and the reusable lambda, and wont even compile.

var dtos =
                _unitOfWork.ProductRepository.All()
                    .Where(myLambda)
                    .Project().To<ProductGridDTO>()
                    .OrderBy(dynamicSort)
                    .Skip(skip)
                    .Take(take)
                    .ToList();

It gives the following compile error:

Error 18

'System.Collections.Generic.IEnumerable' does not contain a definition for 'Project' and no extension method 'Project' accepting a first argument of type 'System.Collections.Generic.IEnumerable' could be found (are you missing a using directive or an assembly reference?)

Code Block 2 uses .Select() and Mapper.Map() and compiles and works, but the SQL query generated returns all columns. I want to use Project().To<> to only return a minimal set of columns in the SQL query, and thus be more efficient and quicker.

var dtos =
                _unitOfWork.ProductRepository.All()
                    .Where(myLambda)
                    .Select(y => Mapper.Map(y, new ProductGridDTO()))
                    .OrderBy(dynamicSort)
                    .Skip(skip)
                    .Take(take)
                    .ToList();

Code Block 3 uses Project().To<> and the same lambda but as inline code. It compiles and works okay, but does not let me reuse my lambda expression.

        var dtos3 =
            _unitOfWork.ProductRepository.All()
                .Where(x => (x.Season.Id == 3))
                .Project().To<ProductGridDTO>()
                .OrderBy(dynamicSort)
                .Skip(skip)
                .Take(take)
                .ToList();

Is there any way I can get Code Block 1 working. Is there another way I can defined my lambda expression to get around this compile error?

Was it helpful?

Solution

IQueryable objects do not work with delegates, they work with Expressions. You initialize them the same way but you must declare it differently.

Expression<Func<Product, bool>> myLambda = x => (x.Season.Id == 3);

Try that out and see if it work.

The problem is because you passed in a delegate you ended up using this version of .Where( which outputs a IEnumerable, The problem is .Project<T>() requires a IQueyable<T> and to get that you must use this version of .Where( which you can see only take in a Expression<Func<TSource, bool>> not a Func<TSource, bool>.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top