在多个EF查询中重用ViewModel材质化器?

时间:2015-04-12 02:10:04

标签: entity-framework linq-to-entities entity-framework-6 linq-expressions

我想重用从实体框架6 IQueryable<TEntity>中水合视图模型的方法。对我来说最直观的是,它看起来像这样:

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);
}

不幸的是,EF尝试将ToViewModel()方法发送到数据库,因此枚举查询结果会导致类似于“此方法无法转换为商店表达式”的异常。

由于性能原因,我通常不希望通过网络加载整个Entity<Record>(以及初始化程序中引用的所有相关对象),否则我可以执行以下操作:

IEnumerable<ViewModel> GetRecords() {
    return
        from record in Context.Records.ToList()
        select ToViewModel(record);
}

我觉得我忽略了Expression打字时相当简单的事情。想法?

1 个答案:

答案 0 :(得分:2)

是的,您认为应该使用Expression。准备方法和新助手,如下所示:

public static Expression<Func<Record, ViewModel>> GetToViewModelExpression() {
    return r => new ViewModel {
        Title = r.Title
    };
}

public static ViewModel ToViewModel(Record record) {
    return GetToViewModelExpression().Compile()(record);
}

并在你的依赖方法中使用它:

// 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());
}