如何在不使用 table 两次的情况下加快我的 LINQ 查询?

How can I speed up my LINQ query without using a table twice?

所以我在查询中使用了两次 table,而且我不知道还有什么方法可以只使用它一次。这是我的查询:

var result = (from t1 in (from t1 in db.Students.Where(en => en.Progress == MyEnum.Accepted).GroupBy(en => en.Class).AsEnumerable()
                          join t2 in dbOther.Classes on t1.Key equals t2.Class 
                          select t2)
              join t3 in (db.Students).AsEnumerable() on t1.Class equals t3.Class into t4
              select new
                          {
                              ClassNum = t1.Class,
                              StartDate = t1.StartDate,
                              Weeks = t1.Weeks,
                              Accepted = t4.Where(e => e.Progress == MyEnum.Accepted).Count(),
                              NotAccepted = t4.Where(e => e.Progress < MyEnum.Accepted).Count()
                          }).ToList();

我只需要 类 有学生处于接受状态。然后我想得到 类 及其整个花名册的计数,甚至是未被录取的学生。有一个更好的方法吗?似乎从同一个 table 读取两次并不是最快的方法。

感谢您的帮助。

除非您真的要在这里简化查询,否则您真的不需要点击 dbOther 来找出 类 有哪些学生处于已接受状态。该信息在 db.

var studentCountPerClass = (from s in db.Students
                            group s by s.Class into studentsByClass    
                            where studentsByClass.Any(x => x.Progress == MyEnum.Accepted)
                            select new
                            {
                                ClassNum = studentsByClass.Key,
                                Accepted = studentsByClass.Count(s => s.Progress == MyEnum.Accepted),
                                NotAccepted = studentsByClass.Count(s => s.Progress < MyEnum.Accepted),
                            })
                            .ToList();

var classCodes = studentCountPerClass.Select(x => x.ClassNum).ToList(); 
var classData = (from c in dbOther.Classes
                    where classCodes.Contains(c.Class)
                    select new {
                        c.Class,
                        // Any other data you want about the class
                    })

不要在学生数据库对象上使用“.Enumerable()”,而是使用 Querable。 这将创建一个表达式,该表达式在数据库级别进行评估,而不是先获取整个学生 table 然后进行比较。

查看这里了解详细信息Returning IEnumerable<T> vs. IQueryable<T>

只是为了尝试,设置探查器并查看为 Enumerable 和 Queryable 生成的查询。差异将在此处说明。

Entity framework 最容易展示,这两种方法在执行上存在差异。也是支持这些功能的最简单的ORM。

首先,从 db.Students table:

中获取有关学生注册的信息
var stats = db.Students
    .GroupBy(en => en.Class)
    .Select(g => new {
        Class = g.Key
    ,   Accepted = g.Count(en => en.Progress == MyEnum.Accepted)
    ,   NotAccepted = g.Count(en => en.Progress < MyEnum.Accepted)
    })
    .Where(g => g.Accepted != 0)
    .ToList();

接下来,从另一个数据库中获取 类:

var classIds = stats.Select(en => en.Class).ToList();
var classes = dbOther.Classes.Where(c => classIds.Contains(c.Class)).ToList();

最后将两者合并成结果:

var result = (from s in stats
    join c in classes on c.ClassId = s.ClassId
    select new {
        ClassNum = c.Class
    ,   c.StartDate
    ,   c.Weeks
    ,   s.Accepted
    ,   s.NotAccepted
    }).ToList();