簡體   English   中英

Entity Framework Core 可以返回視圖模型嗎

[英]Can Entity Framework Core return view model

我有一種情況,可以通過以下類比來解釋。

示例:假設我們有 3 個表Categories => SubCategories => Products

1個類別可以有多個子類別,1個子類別可以有多個產品。

我正在展示帶有類別和子類別名稱的產品詳細信息的簡單卡片,但為此我正在編寫 EF 之類的內容。

var products = await _context.Products
                             .Where(x => x.IsDeleted == false)
                             .Include(x => x.SubCategory)
                             .Include(x => x.SubCategory.Category).ToListAsync()

生成的 SQL 成本太高。

當產品到達控制器時,Automapper 開始根據我需要的視圖模型進行映射。

我是 Entity Framework Core 的新手,我有三個問題:

  1. 有沒有更好的方法來編寫上面的代碼?
  2. 我可以直接從 Entity Framework Core 返回視圖模型嗎? 在上述情況下,我可以返回一個模型,其屬性僅顯示產品、子類別和類別的名稱嗎?
  3. 如果我不能回來,那么我如何說服自己停止使用 Dapper?

Automapper 可以為您生成 sql,基本上是在數據庫中映射到您的視圖模型/DTO。

使用IQueryableProjectTo擴展,解釋here

  1. 是的。 您可以使用ThenInclude操作使代碼更易於閱讀。
var products = await _context.Products.Where(x => x.IsDeleted == false)
                                       .Include(x => x.SubCategory)
                                       .ThenInclude(x => x.Category).ToListAsync()
  1. 是還是不是。 這取決於您的ViewModel是什么。

實體框架是操作數據庫實體的框架。 但是ViewModel是 MVVM 中的一個概念。 這是兩個不同的概念,沒有任何關系。

通常,視圖正在渲染需要渲染的內容。 所以我們返回一個ViewModel而不是Entity 如果Entity本身就是你需要渲染的,就返回它! 沒關系。

return View(viewName: "myview", model: products);
@model IEnumerable<Product> // Product is your entity in EF. You can use it in a view.

沒關系。

但是,請考慮視圖需要的不是您從實體框架中獲得的。 現在您需要將實體轉換為ViewModel 例如:

var entity = await dbContext.MyTable.SingleOrDefaultAsync(t => t.Id == id);
var viewModel = new MyViewModel
{
    Color = entity.Color // Only need to return the color, for example.
}
return View(viewModel);
@model MyViewModel

<h2>The color of it is @Model.Color</h2>
@*You can't access other properties of the entity here in the view.*@

並且其他屬性不會返回到視圖。

AutoMapper類的一些工具可以幫助您完成地圖工作。

另一種方法是使用Select()返回您選擇的列。 例如:

實體定義和視圖模型定義。

public class Product
{
    public int Id { get; set; } // Don't want to return this.
    public string Name { get; set; } // Only want to return this.
}

public class ProductDto
{
    public string Name { get; set; }
}
var products = _context.Products; // While the products is declared, the query was not happened in the database. It only defines an IQueryable object.
List<ProductDto> viewModel = await products.Select(t => new ProductDto
{
    Name = t.Name // Manually map here.
})
.ToListAsync();

return View(viewModel);

在您看來:

@model List<ProductDto>
foreach (var dto in Model)
{
  <h2>dto.Name</h2>
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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