bigtv
bigtv

Reputation: 2711

Map query expression from DTO to Entity Object

I have inherited a code base that uses DTOs in the business layer, these are populated via a set of mappers from Entity Framework. This has some quite serious limitation in terms of querying so I am working on a new "optimised" querying service.

My first issue is that I need to translate my LINQ query on my DTO to work with my Entity object but the calling context has no knowledge of the EF entities. Let's assume we can rely on the properties on each object having matching names.

This is where I have got to in terms of stubbing out what I want:

   public static List<TDataObject> GetFiltered<TDataObject(Expression<Func<TDataObject, TDataObject>> projection, Func<TDataObject, bool> filter)
   {
        // 1. translate the filter parameter to work with my equivalent Entity object

        // 2. build the EF query with the modified filter expression and also a Select() projection so we only return the properties we need. (this should generate an optimised SQL query under the hood)

        // 3. map the results from the EF query back onto my TDataObject and return (I already have AutoMapper maps in place for this)
   }

It is item 1 that I am struggling with so if anyone has any code examples for blogs posts for achieving this I'd appreciate it.

Also if anyone has any alternate suggestions I'd be happy to hear them.

Upvotes: 2

Views: 1694

Answers (1)

Jimmy Bogard
Jimmy Bogard

Reputation: 26765

One way to handle this is to build primitives around queries (instead of layers with repositories etc). Here's what we do:

http://lostechies.com/jimmybogard/2013/10/29/put-your-controllers-on-a-diet-gets-and-queries/

The calling code (controller) knows about a query and the result (DTO), but the piece doing the mapping knows exactly about EF Context/NHibernate ISession. Works very well for us and keeps our controllers light and thin.

Alternatively, get rid of your layers, and expose the EF objects directly:

var dtos = context.Employees.Where(e => e.IsActive)
    .Project().ToArray<EmployeeShowViewModel>();

Put this in the controller because who cares, layers and abstractions are productivity preventers and time wasters.

Upvotes: 1

Related Questions