簡體   English   中英

Web Api 2 + EF6 - 構建DTO

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM