我继承了在业务层中使用DTO的代码库,这些代码库通过Entity Framework中的一组映射器填充。这在查询方面有一些非常严重的限制,所以我正在开发一种新的“优化”查询服务。
我的第一个问题是我需要在我的DTO上翻译我的LINQ查询以使用我的Entity对象,但是调用上下文不知道EF实体。假设我们可以依赖具有匹配名称的每个对象的属性。
这就是我在剔除我想要的东西方面所需要的:
public static List<TDataObject> GetFiltered<TDataObject(Expression<Func<TDataObject, TDataObject>> projection, Func<TDataObject, bool> filter)
{
// 1. translate the filter parameter to work with my equivalent Entity object
// 2. build the EF query with the modified filter expression and also a Select() projection so we only return the properties we need. (this should generate an optimised SQL query under the hood)
// 3. map the results from the EF query back onto my TDataObject and return (I already have AutoMapper maps in place for this)
}
我正在努力争取第1项,所以如果有人为博客提供任何代码示例,我会很感激。
如果有人有任何其他建议,我很乐意听到。
答案 0 :(得分:1)
处理此问题的一种方法是围绕查询构建基元(而不是使用存储库等的层)。这就是我们的工作:
http://lostechies.com/jimmybogard/2013/10/29/put-your-controllers-on-a-diet-gets-and-queries/
调用代码(控制器)知道查询和结果(DTO),但执行映射的部分确切地知道EF Context / NHibernate ISession。对我们非常有效,并使我们的控制器轻薄。
或者,摆脱你的图层,直接暴露EF对象:
var dtos = context.Employees.Where(e => e.IsActive)
.Project().ToArray<EmployeeShowViewModel>();
将它放在控制器中,因为谁在乎,层和抽象是防止生产力和时间浪费。