[英]Web Api 2 + EF6 - Building a DTO
For a project we are making use of EF and Web Api 2. To abstract away from our database models we are making use of DTO's. 对于一个项目,我们正在使用EF和Web Api 2.为了从我们的数据库模型中抽象出来,我们正在使用DTO。 We have a factory to construct these DTO's:
我们有一个工厂来建造这些DTO:
public class FooFactory:IModelConverter<FooDTO, Foo>
{
public FooDTO Create(Foo data)
{
return new FooDTO()
{
//Some fields
};
}
}
In our Api call we can do: 在我们的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);
}
This works, but implies that, after we execute the query, we have to loop over all our results and convert each model to a DTO. 这有效,但暗示在执行查询后,我们必须遍历所有结果并将每个模型转换为DTO。
On the other hand, we could do: 另一方面,我们可以这样做:
public async Task<IHttpActionResult> GetFoo()
{
var foos = db.Foos
//DO STUFF
return Ok(await foos.Select(m => new FooDTO() {
//Assign fields
}).ToListAsync());
}
Which would integrate this projection into the query executed by EF. 哪个会将此投影集成到EF执行的查询中。 But this exposes all the inner details of the FooDTO and we have to repeat all this creation code.
但这暴露了FooDTO的所有内部细节,我们必须重复所有这些创建代码。
Is there a way to do something like: 有没有办法做这样的事情:
public async Task<IHttpActionResult> GetFoo()
{
var foos = db.Foos
//DO STUFF
return Ok(await foos.Select(m => _converter.Create(m)).ToListAsync());
}
which does not work, because Linq to Entities can't deal with the create function. 哪个不起作用,因为Linq to Entities无法处理create函数。
I'm also open to alternative ways to work with DTO's, is there a better way to do this, or is there no way to avoid the extra pass through all query results? 我也对使用DTO的其他方法持开放态度,是否有更好的方法可以做到这一点,或者没有办法避免额外传递所有查询结果?
Oh, the catch, I want to do this without automapper. 哦,抓住了,我想在没有自动播放器的情况下做到这一点。
First, it seems more like a code review question. 首先,它似乎更像是一个代码审查问题。 I suggest you to not use entity framework (db in your code) directly in your controller.
我建议你不要在控制器中直接使用实体框架(代码中的db)。 Controllers should be thin, and query logic can be very complex.
控制器应该很薄,查询逻辑可能非常复杂。 There are many situations when you need to query data from your database that cannot be mapped to entities.
在许多情况下,您需要从数据库中查询无法映射到实体的数据。 Because of that you can create repository classes that directly return DTO's:
因此,您可以创建直接返回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();
}
}
}
Another advantage of this approach is that you query only data you really need, and now whole entity. 这种方法的另一个优点是,您只查询您真正需要的数据,现在只查询整个实体。
Note: await is necessary - cannot return Task directly here. 注意:等待是必要的 - 不能直接在这里返回任务。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.