Reputation: 13848
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?
Upvotes: 4
Views: 1983
Reputation: 5314
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();
Upvotes: 2
Reputation: 15413
You may use Queryable Extensions from AutoMapper
The .ProjectTo() will tell AutoMapper's mapping engine to emit a select clause to the IQueryable that will inform entity framework that it only needs to query the Name column of the Item table, same as if you manually projected your IQueryable to an OrderLineDTO with a Select clause.
Upvotes: 1