Может ли Entity Framework Core вернуть модель представления - PullRequest
1 голос
/ 26 января 2020

У меня есть ситуация, которую можно объяснить приведенной ниже аналогией.

Пример: Допустим, у нас есть 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 запускает магию c для отображения в соответствии с моей требуемой моделью представления.

Я новичок в Entity Framework Core и у меня есть три вопроса:

  1. Есть ли лучший способ написания кода выше?
  2. Можно ли вернуть модель представления непосредственно из Entity Framework Core? В приведенном выше случае, могу ли я вернуть модель со свойствами, отображающими только названия продуктов, подкатегорий и категорий?
  3. Если я не могу вернуться, то как я могу убедить себя прекратить использование Dapper?

Ответы [ 2 ]

2 голосов
/ 26 января 2020

Automapper может сгенерировать sql для вас, в основном делая отображение вашей viewmodel / DTO в базе данных.

Используйте расширение ProjectTo для IQueryable, объяснено здесь .

1 голос
/ 26 января 2020
  1. Да. Вы можете использовать операцию ThenInclude, чтобы облегчить чтение кода.
var products = await _context.Products.Where(x => x.IsDeleted == false)
                                       .Include(x => x.SubCategory)
                                       .ThenInclude(x => x.Category).ToListAsync()
Да или нет. Это зависит от того, чем является 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.

Это нормально.

Но, подумайте, что нужно, а не то, что вы получили от Right-Framework. Теперь вам нужно преобразовать сущность в 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>
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...