I'd like to reuse the method that hydrates a view model from an Entity Framework 6 IQueryable<TEntity>
. Most intuitively to me, that would look something like this:
ViewModel ToViewModel(Record record) {
return new ViewModel {
Title = record.Title
}
}
// Get a single ViewModel
ViewModel GetRecord(int id) {
return ToViewModel(Context.Records.Find(id));
}
// Get multiple ViewModels
IEnumerable<ViewModel> GetRecords() {
return
from record in Context.Records
select ToViewModel(record);
}
Unfortunately EF tries to send the ToViewModel()
method to the database, so enumerating the query result causes an Exception similar to "this method cannot be translated into a store expression".
Typically I'd prefer not to load the entire Entity<Record>
(and all related objects referenced in the initializer) over the wire for performance reasons, otherwise I could do the following:
IEnumerable<ViewModel> GetRecords() {
return
from record in Context.Records.ToList()
select ToViewModel(record);
}
I feel like I'm overlooking something fairly simple with Expression
typing. Thoughts?
Yes, you think correctly that you should use Expression. Prepare the method, and a new helper, like this:
public static Expression<Func<Record, ViewModel>> GetToViewModelExpression() {
return r => new ViewModel {
Title = r.Title
};
}
public static ViewModel ToViewModel(Record record) {
return GetToViewModelExpression().Compile()(record);
}
And use it in your dependent methods like this:
// Get a single ViewModel
ViewModel GetRecord(int id) {
return ToViewModel(Context.Records.Find(id));
}
// Get multiple ViewModels
IEnumerable<ViewModel> GetRecords() {
return Context
.Records
.Select(GetToViewModelExpression());
}