[英]Web Api 2 + EF6 - Building a DTO
对于一个项目,我们正在使用EF和Web Api 2.为了从我们的数据库模型中抽象出来,我们正在使用DTO。 我们有一个工厂来建造这些DTO:
public class FooFactory:IModelConverter<FooDTO, Foo>
{
public FooDTO Create(Foo data)
{
return new FooDTO()
{
//Some fields
};
}
}
在我们的Api电话中,我们可以做到:
public async Task<IHttpActionResult> GetFoo()
{
var foos = db.Foos
//DO STUFF
var dtos = (await foos.ToListAsync()).Select(m => _converter.Create(m)); //Converter is an instance of FooFactory)
return Ok(dtos);
}
这有效,但暗示在执行查询后,我们必须遍历所有结果并将每个模型转换为DTO。
另一方面,我们可以这样做:
public async Task<IHttpActionResult> GetFoo()
{
var foos = db.Foos
//DO STUFF
return Ok(await foos.Select(m => new FooDTO() {
//Assign fields
}).ToListAsync());
}
哪个会将此投影集成到EF执行的查询中。 但这暴露了FooDTO的所有内部细节,我们必须重复所有这些创建代码。
有没有办法做这样的事情:
public async Task<IHttpActionResult> GetFoo()
{
var foos = db.Foos
//DO STUFF
return Ok(await foos.Select(m => _converter.Create(m)).ToListAsync());
}
哪个不起作用,因为Linq to Entities无法处理create函数。
我也对使用DTO的其他方法持开放态度,是否有更好的方法可以做到这一点,或者没有办法避免额外传递所有查询结果?
哦,抓住了,我想在没有自动播放器的情况下做到这一点。
首先,它似乎更像是一个代码审查问题。 我建议你不要在控制器中直接使用实体框架(代码中的db)。 控制器应该很薄,查询逻辑可能非常复杂。 在许多情况下,您需要从数据库中查询无法映射到实体的数据。 因此,您可以创建直接返回DTO的存储库类:
class FooRepository
{
public async Task<List<FooDTO>> FindAsync()
{
using(var context = new DbContext())
{
return await context.Foos
.Select(m => new FooDTO
{
Id = m.Id,
...
})
.ToListAsync();
}
}
}
这种方法的另一个优点是,您只查询您真正需要的数据,现在只查询整个实体。
注意:等待是必要的 - 不能直接在这里返回任务。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.