Projection of single entities in EF with extension methods

c# entity-framework expression-trees


I like to do projection from my entity models into my view models using extension methods. This means I dont over/under fetch for my models and it makes the code nice and readable. It makes sense that sometimes the projections may include nested models, and I want to get reuse on those sub-projections.

I want to be able to do something like the following:

ctx.People.FiltersAndThings().ToViewModels();//the project my DB Models into view models

Extension methods for actual projection

public static IQueryable<PersonModel> ToViewModels(this IQueryable<Person> entities)
    return entities.Select(x => new PersonModel {
        Me = x.Me.ToViewModel(), //this method cannot be translated into a store expression
        Friends = x.Friends.AsQueryable().ToViewModels() //works fine with some magic (tm)

public static IQueryable<ProfileModel> ToViewModels(this IQueryable<Profile> entities)
    return entities.Select(x => new ProfileModel { Name = x.Name });

public static ProfileModel ToViewModel(this Profile entity)
    return new ProfileModel { Name = entity.Name };

When using a Queryable (eg Friends = x.Friends.AsQueryable().ToViewModels()) we can use some magic to flatten this to an expression (see, answer by @LordTerabyte) But when we are doing an assignment with a new clause (eg Me = new ProfileModel { Name = x.Me.Name }) its not an expression so if we bundle this under an extension method (eg Me = x.Me.ToViewModel()) we can't flatten this to an expression.

How does an assignment to a new object work under the scenes in EF?

Is there a way to do convertion to a new object via an extension method?

Full demo code here:


I now have a blog post (Composable Repositories - Nesting Extensions) and nuget package to help with nesting extension methods in linq

5/23/2017 10:30:49 AM

Accepted Answer

Take a look at this answer. It does a very similar thing what you want. Basically you would define your transformation as an Expression tree, e.g:

public static Expression<Func<Profile, ProfileModel>> ToProfileViewModel()
    return entity => new ProfileModel { Name = entity.Name };

And then do invocations of this (e.g. ExpressionsHelper.ToProfileViewModel().AsQuote()(p)).

If you prefer, you can modify the visitors, to allow a nicer syntax. Something along the lines:

public static ProfileModel ToViewModel(this Profile profile)
    // this implementation is only here, so that if you call the method in a non expression tree, it will still work
    return ExpressionsHelper.ToProfileViewModel().Compile()(profile); // tip: cache the compiled func!

Now you need to create a visitor, that checks all method calls, and when finds a method with this attribute, it changes the whole call to ExpressionsHelper.ToProfileViewModel().AsQuote()(profile). This is as an exercise for you :) }

5/23/2017 11:55:16 AM

Related Questions

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow