загружать связанные объекты без использования include в Entity Framework Core - PullRequest
0 голосов
/ 26 июня 2018

Я предназначен для загрузки связанных объектов без использования include в C # / Entity Framework. В моем примере я использовал левое соединение для загрузки всех вариантов вопросов, которые отображаются, только если я явно говорю в операторе выбора в запросе LINQ. Мой вопрос, как я могу гарантировать, что он загружает связанные объекты, не определяя связанные объекты в select внутри запроса LINQ.

Модель данных

public class QuestionDataModel : BasicDataModel
{
    public QuestionDataModel()
    {            
        QuestionOptions = new HashSet<QuestionOptionDataModel>();

    }

    public Guid Id { get; set; }

    public virtual ICollection<QuestionOptionDataModel> QuestionOptions { get; set; }

}

LINQ Query

var q1 = (
           from question in Context.Questions
            join options in Context.QuestionOptions on question.Id equals options.QuestionId into qo
             where question.ConsultationId == Guid.Parse("10324003-0012-4D99-95D8-7E7189CA3888")
                select new
                  {
                    question
                    //,qo  // it only loads questionOption if qo is here, I need to do without that, since it is collection property in QuestionDataModel class
                  }
           ).ToList();

1 Ответ

0 голосов
/ 26 июня 2018

Одним из более медленных элементов диалога с базой данных является передача выбранных данных из системы управления базами данных в ваш процесс. Желательно не отправлять в ваш процесс больше данных, чем вы планируете использовать.

Очевидно, у вас есть последовательность Questions, где каждый Question имеет ноль или более QuestionOptions, а каждый QuestionOption принадлежит ровно одному Question, а именно Question с Id, равным QuestionOption.QuestionId. Простой один ко многим с внешним ключом в QuestionId.

Если вы получите Question с Id == 4 с десятью тысячами QuestionOptions, вы знаете, что у каждого QuestionOption будет QuestionId со значением 4. Вы будете передавать значение 4 10 тысяч раз, хотя вы, вероятно, даже не будете его использовать, поскольку вы уже знаете, что он равен Question.Id.

Решения: используйте «Включить», только если вы планируете обновить элемент базы данных. Во всех остальных случаях используйте Select. Выберите только те свойства, которые вы действительно планируете использовать.

В синтаксисе метода (или используйте аналогичный синтаксис запроса, если хотите)

var result = context.Questions.Join(context.QuestionOptions, // join Questions and QuestionOptions
    question => question.Id,                      // from every Question take the Id
    questionOption => questionOption.QuestionId,  // from every Option take the QuestionId
    (question, questionOption) => new              // when they match make a new object
    {    // Select only the properties you plan to use:
         Question = new 
         {
             Id = question.Id,
             ... other question properties
         },
         Option = new
         {
             Id = questionOption.Id,
             // not needed: questionOption.QuestionId, it equals Question.Id
             ... other properties you plan to use
         }
    });

Делайте ToList, только если вы действительно планируете использовать все извлеченные элементы. Сохраняйте свой результат в IQueryable как можно дольше.

Если у вас есть каждый Question with its QuestionOptions, рассмотрите возможность использования Queryable.GroupBy

var questionsWithTheirOptions = context.Questions
   .GroupJoin(context.QuestionOptions,            // GroupJoin Questions and QuestionOptions
    question => question.Id,                      // from every Question take the Id
    questionOption => questionOption.QuestionId,  // from every Option take the QuestionId
    (question, optionsOfQuestion) => new          // when they match make a new object
    {   // desired Question Properties
        Id = question.Id,
        ...

        // The options of this question:
        Options = optionsOfQuestion.Select(option => new
        {
            Id = questionOption.Id,
            // not needed: questionOption.QuestionId, it equals Question.Id
            ... 
        })
        .ToList()
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...