Работа с представлениями SQL в ядре Entity Framework

Например, у меня есть такая модель:

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public BlogImage BlogImage { get; set; }
}

public class BlogImage
{
    public int BlogImageId { get; set; }
    public byte[] Image { get; set; }
    public string Caption { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
} 

Я хочу вернуться в ImageView представление URL и Изображение.

Где мне нужно создать и определить это представление SQL?

Ответ 1

В Entity Framework Core 2.1 мы можем использовать типы запросов, как предложил Юрий Н.

Более подробную статью о том, как их использовать, можно найти здесь

. Наиболее простой подход в соответствии с примерами из статьи:

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

public class Magazine
{
  public int MagazineId { get; set; }
  public string Name { get; set; }
  public string Publisher { get; set; }
  public List<Article> Articles { get; set; }
}

public class Article
{
  public int ArticleId { get; set; }
  public string Title { get; set; }
  public int MagazineId { get; set; }
  public DateTime PublishDate { get;  set; }
  public Author Author { get; set; }
  public int AuthorId { get; set; }
}
public class Author
{
  public int AuthorId { get; set; }
  public string Name { get; set; }
  public List<Article> Articles { get; set; }
}

2. У нас есть представление с именем AuthorArticleCounts, определенное для возврата названия и количества статей, написанных автором

SELECT
  a.AuthorName,
  Count(r.ArticleId) as ArticleCount
from Authors a
  JOIN Articles r on r.AuthorId = a.AuthorId
GROUP BY a.AuthorName

3. Мы идем и создаем модель, которая будет использоваться для вида

public class AuthorArticleCount
{
  public string AuthorName { get; private set; }
  public int ArticleCount { get; private set; }
}

4. После этого мы создаем свойство DbQuery в моем DbContext для использования результатов просмотра внутри модели

public DbQuery<AuthorArticleCount> AuthorArticleCounts{get;set;}

5. Наконец, мы легко можем получить результаты просмотра следующим образом.

var results=_context.AuthorArticleCounts.ToList();

UPDATE Согласно комментарию ссугнеза

Стоит отметить, что DbQuery больше не будет/не поддерживается в EF Core 3.0

Ответ 2

Представления в настоящее время не поддерживаются Entity Framework Core. Смотрите https://github.com/aspnet/EntityFramework/issues/827.

Тем не менее, вы можете обмануть EF в использовании представления, отображая вашу сущность в представление, как если бы это была таблица. Этот подход имеет ограничения. например вы не можете использовать миграции, вам нужно вручную указать ключ для EF, и некоторые запросы могут работать некорректно. Чтобы обойти эту последнюю часть, вы можете писать SQL-запросы вручную

context.Images.FromSql("SELECT * FROM dbo.ImageView")

Ответ 3

Вот новый способ работы с представлениями SQL в EF Core: Типы запросов.

Ответ 4

EF Core не создает DBset для представлений SQL автоматически в контексте calss, мы можем добавить их вручную, как показано ниже.

public partial class LocalDBContext : DbContext
{ 

    public LocalDBContext(DbContextOptions<LocalDBContext> options) : base(options)
    {

    }

    public virtual DbSet<YourView> YourView { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<YourView>(entity => {
            entity.HasKey(e => e.ID);
            entity.ToTable("YourView");
            entity.Property(e => e.Name).HasMaxLength(50);
        });
    }

}

Образец образца определяется ниже, с несколькими свойствами

using System;
using System.Collections.Generic;

namespace Project.Entities
{
    public partial class YourView
    {
        public string Name { get; set; }
        public int ID { get; set; }
    }
}

После добавления класса для представления и DB, заданного в классе контекста, вы можете использовать объект вида через свой объект контекста в контроллере.

Ответ 5

QueryTypes является каноническим ответом EF Core 2.1, но есть другой способ, который я использовал при переходе с первого подхода базы данных (представление уже создано в базе данных):

  • определить модель для сопоставления столбцам вида (либо сопоставить имя класса модели с именем представления, либо использовать атрибут таблицы. Убедитесь, что атрибут [Key] применен хотя бы к одному столбцу, в противном случае выборка данных завершится неудачей
  • добавьте DbSet в ваш контекст
  • добавить миграцию (Add-Migration)
  • удалить или закомментировать код для создания/удаления "таблицы", которая будет создана/удалена на основе предоставленной модели
  • обновить базу данных (Update-Database)