How can I create a reusable Entity Framework projection expression?

.net c# entity-framework entity-framework-6 linq-to-entities

Question

In my database, there are tables with dozens of columns:

Table MyEntity: int Id string Name string Email ...dozens of other columns I never use in this project

The class generated by EF has properties for those extra columns, and a simple query gets all those extra columns, wastefully.

Instead, I want to have a thin class, like so:

class MyEntity { public int Id; public string Name; public string Email; }

When I query, I want to create instances of my thin object, and obviously, I can do this:

from x in MyEntity
select new MyEntity {Id = x.Id, Name = x.Name, Email = x.Email };

But I do this a lot, and typing out the properties every time gets very tedious (and error prone, because I could forget one).

So I'm trying to do something like this instead:

from x in MyEntity
select x.ToLiteEntity();

But I'm not sure how to write ToLiteEntity so that it creates an expression that gets added to the query, so that it knows to select only the needed columns from the database. How can I do this?

1
4
1/13/2016 4:34:21 PM

Popular Answer

You can abstract this to a layer above the database. When you want to retrieve your 'lite' objects, call a separate method:

public IQueryable<MyEntity> GetLiteMyEntities(DbContext c, string Name) // your implementation of DbContext, not actually DbContext
{
    return from me in c.MyEntity 
        select new MyEntity {Id = x.Id, Name = x.Name, Email = x.Email };
}

EDIT: If you need to filter on other fields that you don't want to return, you can compose your filter query first, and then use a method that takes an IQueryable:

public IQueryable<MyEntity> GetLiteMyEntities(IQueryable<MyEntity> query)
{
    return from me in query 
        select new MyEntity {Id = x.Id, Name = x.Name, Email = x.Email };
}

// build your filter first
from x in MyEntity 
where x.someSpecialID == 42
select x;

// then pass it to get your lite object
var lite = GetLiteMyEntities(x);

Even better, make it an extension method:

public IQueryable<MyEntity> GetLiteMyEntities(this IQueryable<MyEntity> query)
{
    return from me in query 
        select new MyEntity {Id = x.Id, Name = x.Name, Email = x.Email };
}

var lite = (from x in MyEntity 
where x.someSpecialID == 42
select x).GetLiteMyEntities();
2
1/13/2016 7:30:33 PM


Related Questions





Related

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