如何使用Where条件包含在实体框架LINQ中?

时间:2018-04-19 06:06:31

标签: entity-framework linq

我的示例代码行是,

            var question = context.EXTests
                .Include(i => i.EXTestSections.Where(t => t.Status != (int)Status.InActive))
                .Include(i => i.EXTestQuestions)
            .FirstOrDefault(p => p.Id == testId);

此处Include不支持Where条款。如何修改上面的代码?

1 个答案:

答案 0 :(得分:1)

您有一系列ExTests。每个ExText都有零个或多个ExTestSections,每个Extest也有一个属性ExtestQuestions,它可能也是一个序列。最后,每个ExTest都由Id标识。

您需要一个查询,其中您获得Id等于testId的第一个ExTest,包括其所有ExTestQuestions和一些ExTestSections。您只需要那些具有InActive状态的ExTestSections。

使用选择而不是使用

数据库查询的一个较慢的部分是将数据从DBMS传输到您的进程。因此,明智的做法是将其限制为您实际计划使用的数据。

您似乎已经设计了ExTests与其ExTestSections之间的一对多关系:每个ExTest都有零个或多个ExTestSections,每个ExTestSection只属于一个ExTest。在数据库中,这是通过向ExTestSection提供其所属的ExTest的外键来完成的。可能是您设计了多对多关系。原则保持不变。

如果您向ExTest询问其百个ExTestSections,您将获得ExTest的Id和ExTestSection的外键值的百倍,从而发送相同的值101次。多么浪费。

因此,如果您从数据库中查询数据,则只查询您实际计划使用的数据。

  

如果您计划更新查询数据,请使用包含,否则使用选择

回到你的问题

var result = myDbContext.EXTests
    .Where(exTest => exTest.Id == testId)
    .Select( exTest => new
    {
        // only select the properties you plan to use
        Id = exTest.Id; 
        Name = exTest.Name,
        Result = exText.Result,
        ... // other properties

        ExTestSections = exTest.Sections
            .Where(exTestSection => exTestSection.Status != (int)Status.InActive)
            .Select(exTestSection => new
            {
                 // again: select only those properties you actually plan to use
                 Id = exTestSection.Id,

                 // foreign key not needed, you know it equals ExTest primary key
                 // ExTestId = exTestSection.ExtTestId

                 ... // other ExtestSection properties you plan to use
            })
            .ToList(),

            ExTestQuestions = exTest.ExTestQuestions
                .Select( ...) // only the properties you'll use
    })
    .FirstOrDefault();

我已将相同TestId的测试转移到Where。这将允许您省略所请求项目的Id:您知道它将等于testId,因此无法转移它。