在不使用Entity Framework Core包含的情况下加载相关实体

时间:2018-06-26 11:36:04

标签: linq entity-framework-core

我打算在不使用C#/ Entity Framework中包含的情况下加载相关实体。 在我的示例中,我使用了左联接来加载所有问题选项,这些选项仅在我在LINQ查询的select语句中明确地说出时才显示。我的问题是如何确保在LINQ查询中的select中没有定义相关实体的情况下加载相关实体。

数据模型

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

    }

    public Guid Id { get; set; }

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

}

LINQ查询

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 :(得分:1)

数据库对话的较慢元素之一是将所选数据从数据库管理系统传输到您的流程。明智的是,不要向您的进程发送比您实际计划使用的数据更多的数据。

显然,您有一个Questions序列,其中每个Question具有零个或多个QuestionOptions,每个QuestionOption恰好属于一个Question,即QuestionId相等的QuestionOption.QuestionId。在QuestionId中带有外键的简单一对多。

如果您要获取ID == 4的Question及其一万个QuestionOptions,则知道每个QuestionOption都会有一个QuestionId,其值为4.您将以一万次的次数传输该值4,而您可能甚至不会使用它,因为您已经知道它等于Question.Id

  

解决方案是:仅当您计划更新数据库项目时才使用包括。   在所有其他情况下,请使用“选择”。   仅选择您实际打算使用的属性。

方法中的语法(或根据需要使用类似的查询语法)

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()
    });