Как узнать, включены ли связанные данные при использовании быстрой загрузки в Entity Framework?

Я работаю над проектом, использующим шаблон репозитория. Мы используем Entity Framework для извлечения данных из базы данных. Для загрузки связанных данных мы используем активную загрузку, что означает, что мы должны явно указать данные, связанные с включать.

Скажем, мы хотим, чтобы все блоги и связанные с ними сообщения мы должны были написать:

_dbContext.Blogs.Include(b => b.Posts)

Недостатком этого является то, что вы можете видеть только те связанные данные, которые загружены в класс репозитория.

Я попытался показать пример ниже. Здесь проблема возникает в классе BlogViewModel.cs, потому что вы пытаетесь получить доступ к blogs.Posts, но сообщения не включены в исходный запрос. Поэтому, если вы пытаетесь получить связанные данные, нужно будет проверить источник запроса и посмотреть, включен ли он.

Repository.cs:

public IEnumerable<BlogDbModel> GetBlogs()
{
    return _dbContext.Blogs.ToList();
}

Service.cs:

public IEnumerable<BlogViewModel> GetBlogs()  
{
    return _repository.Select(x => new BlogViewModel(x));
}

BlogViewModel.cs:

public class BlogViewModel 
{
    public BlogViewModel(BlogDbModel blogDbModel)  
    {
        Name = blogDbModel.Name;
        Posts = blogDbModel.Posts;
    }
 
    public string Name { get; set; }
    public IEnumerable<Posts> Posts { get; set; }
}

У кого-нибудь есть умное решение для этого? Возможно ли дать ошибку компиляции, если вы пытаетесь получить доступ к данным, которые не включены?

Два варианта, о которых я подумал:

  1. Вместо этого используйте ленивую загрузку
  2. Всегда возвращайте IQueryable из репозитория

Спасибо

Не могли бы вы поделиться фрагментом вывода, когда вы включаете сообщения в запрос?

M.B. 29.05.2019 09:04

[ { Название: 'Блог Джонни', Сообщения: [ { title: 'Жизнь в дороге}' text: 'Всем привет... }, { title: 'Где я}' text: 'Так здорово... ] }], { Имя: 'Chrisitinas place', Сообщения: [ ....... ] } ]

Moddaman 29.05.2019 09:13

Это то, что вы имели в виду @Innominatum? :С

Moddaman 29.05.2019 09:14

Да, глядя на ваш фрагмент, список сообщений загружен, но пуст, есть ли связь между данными BlogViewModel и сообщениями?

M.B. 29.05.2019 09:53

Я думаю, что мой вопрос, возможно, был истолкован неправильно. @Элдо понял. спасибо за попытку :)

Moddaman 29.05.2019 10:38
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
44
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нет, у вас нет возможности указать ошибку компиляции в этом контексте. Данные в любом случае загружаются во время выполнения.

Ленивая загрузка Предполагая, что вы отображаете блоги, сообщения, комментарии, поэтому вам нужно загружать все при загрузке страницы. Когда вы включаете lazyload и свойства карты, которые не были включены в запрос уровня данных, он будет загружать связанные объекты.

public BlogViewModel(BlogDbModel blogDbModel) 
{
  Name = blogDbModel.Name;
  Posts = blogDbModel.Posts;
 }

Если вы включите отложенную загрузку и сделаете это, этот пост будет загружен с использованием функции отложенной загрузки. Что, если сообщение содержит ссылку на User или любой другой объект, он также загрузит их. Когда вам нужно все в первую очередь, не рекомендуется использовать отложенную загрузку, потому что это потребует дополнительного обращения к базе данных.

IQueryable из репозитория

Я бы сказал, что IQueryable для модели представления — это дырявая абстракция. В идеале ваш уровень данных должен выполнять это. Предоставление IQuerable<BlogDbModel> для Viewmodel похоже на то, что разработчик может получить 1Blogs=>Post=>User=>Accounts1 что-либо связанное с этим.

ИМХО, я бы написал методы уровня данных, которые необходимы для представления.

LazyloadingEnabled = false;

public IEnumerable<BlogDbModel> GetBlogs()
{

    return _dbContext.Blogs.ToList();
}

public IEnumerable<BlogDbModel> GetBlogsAndPosts()
{

  return _dbContext.Blogs.Include("Posts").ToList();
}

//This will fetch only what is needed (You can customize to get columns what is needed)
public IEnumerable<NewCustomDTO> GetBlogsAndPostCount()
{

   return _dbContext.Blogs.Select(x=> NewCustomDTO
   {
       BlogName = x.BlogName,
       Count = x.Posts.Count(),
   });
}

Хорошо. это хороший момент. Проблема с этим подходом заключается в том, что Блоги имеет десять связанных сущностей, у которых снова есть несколько сущностей. Поэтому в репозитории пришлось бы делать много методов. GetBlogsAndPosts, GetBlogsAndPostsAndAuthors и т. д. Я предполагаю, что мой подход будет простой конечной точкой GetBlogs и конечной точкой GetBlogsAndRelatedData.

Moddaman 29.05.2019 10:37

Я думаю, GetBlogs всегда нужны авторы, комментарии и лайки. Простые методы, такие как GetBlogs, которые возвращают только блоги, необходимы при его использовании. Я бы сказал, напишите методы, что необходимо. В разработке нет серебряной пули, но есть компромиссы, которые лучше всего подходят для вашей ситуации.

Eldho 29.05.2019 10:41

Случай с блогами и постами был просто для примера :). На самом деле это нечто гораздо более скучное :). Спасибо еще раз

Moddaman 29.05.2019 10:42

некоторые справочные мысли о ленивой загрузке ardalis.com/avoid-lazy-loading-entities-in-asp-net-приложения

Eldho 29.05.2019 10:44

Другие вопросы по теме