简体   繁体   English

Web Api 2 + EF6 - 构建DTO

[英]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.

相关问题 使用Web.API v.1和EF6运行Breeze吗? - Run Breeze with Web.API v.1 and EF6? VS 2015 ASP.NET Web API(EF6)和Xamarin Enable-Migrations失败 - VS 2015 ASP.NET Web API (EF6) & Xamarin Enable-Migrations fails 如何使用EF6 for Web API为域模型创建可选的日志记录属性? - How to create optional logging properties for a domain model using EF6 for a Web API? 无法在Visual Studio 2015 Web API项目中启用EF6迁移 - Unable to Enable EF6 Migrations in Visual Studio 2015 Web API project 在带有EF6模型的WEB API中,如何限制返回的VARCHAR(MAX)列的长度 - In WEB API with EF6 models, how do I limit the length of a VARCHAR(MAX) column returned DB-First与ASP.NET Web API 2 + EF6的身份验证混淆 - DB-First authentication confusion with ASP.NET Web API 2 + EF6 如何在Restful Web API(.NET / JSON / EF6)服务器端实现部分更新(PATCH) - How to implement Partial Updates (PATCH) in Restful Web API (.NET/ JSON/ EF6) Server side 将EF6与自定义Api分离 - Decoupling EF6 from its custom Api SQLite EF6异步API引发InvalidCastException - SQLite EF6 Async API throws InvalidCastException 关系多对多 EF6 Fluent API - Relation Many to Many EF6 Fluent API
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM