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