C# 实体框架在添加“where子句”时花费太多时间

C# 实体框架在添加“where子句”时花费太多时间,c#,asp.net-mvc,entity-framework,linq,C#,Asp.net Mvc,Entity Framework,Linq,我正在研究学校系统,这个系统有很多用户窃取者和管理者 工具 Asp.net 5 MVC与C VS 2015 SQL SERVER Azure 代码优先方法 分配给一个或多个类的每个用户 用户应该只看到他的类和类内的学生 在另一边 捕捉每个用户类 我写过这个方法 public static IEnumerable<Class> GetClasses() { string UserId = HttpContext.Current.User.Identity.GetUserId()

我正在研究学校系统,这个系统有很多用户窃取者和管理者

工具

Asp.net 5 MVC与C VS 2015

SQL SERVER Azure

代码优先方法

分配给一个或多个类的每个用户

用户应该只看到他的类和类内的学生

在另一边

捕捉每个用户类

我写过这个方法

public static IEnumerable<Class> GetClasses()
{
    string UserId = HttpContext.Current.User.Identity.GetUserId();

    ApplicationDbContext db = new ApplicationDbContext();
    var Job = db.Jobs.Where(j => j.UserId == UserId).FirstOrDefault();
    if (Job.EntityLevelID == 1)
    {
        var x = db.Classes.Where(a => a.Levels.SupervisionCenter.Organization.Id == Job.EntityID) as IEnumerable<Class>;
        return x;
    }
    return null;
}
这段代码将给所有的学生,它需要大约10秒来加载和完成所有的数据,但这是不需要的Bcs,我需要对ClassID字段进行过滤

当我需要筛选基于用户权限的类时

我已将代码编辑为

    var items = db.Students.AsEnumerable().Where(o => o.Name.ToLower().Contains(search))
        .Where(s => UserDB.GetClasses().Select(c => c.Id).Contains(s.ClassID.Value))
        .AsQueryable();
在上一个例子中,当我添加where查询时,需要80秒以上的时间

编辑1 组织结构图将是

组织机构

监督中心

学校

班级

所以我不知道我在这里遇到了什么问题,你能给我一些建议吗


感谢和问候。

让你慢下来的第一件事是数不清的

请参见使用AsEnumerable的效果

基本上,您是在内存中获取所有学生,然后在应用程序内存中运行where子句,而不是仅获取选定的学生

编辑1:

我认为您不需要这样做,因为默认情况下MSSQL不区分大小写。这样就不需要db.Students.AsEnumerable了

编辑2:

为什么不使用join?这将是一个很好的优化开始

差不多

List<Student> data = (from student in db.Students
join clss in db.Classes on student.Class equals clss
where student.Name.Contains(search)).ToList()

这解决了我的问题,只需要3到4秒

    int[] Classes = UserDB.GetClasses().Select(c => c.Id).ToArray();

    var items = db.Students.Where(o => o.Name.ToLower().Contains(search))
        .Where(r => Classes.Contains(r.ClassID.Value)).AsQueryable();

假设您有可用的ServerManagementStudio,我建议您在进行这些查询时运行SQLProfiler。很明显,为什么查询这么慢。使用AsEnumerable将从数据库加载整个表。我假设GetClass也会从中加载完整的数据db@TiesonT. 我已经运行了探查器,我显示执行了大约1000条语句。@StephanBauer,但这不是强制性的吗?Bcs我有remore AsEnumerable代码抛出一个错误我尝试remore IEnumerable它给我这个错误'LINQ to Entities无法识别方法'System.Collections.Generic.IEnumerable'1 GetClasses'方法,并且这个方法不能转换成存储表达式'yes'。没错。GetClasses方法做什么?它检索用户类,顺便说一句,我已经包含在线程中了。我不能像你建议的Bcs那样使用它,我需要一个静态类来完成这个任务,Bcs这个查询将在多个页面或控制器中执行。是的,你需要去掉GetClasses,我想包括你的DB结构。。可能会提出更好的方法。为什么你不能使用导航道具和延迟加载或快速加载。。。这比GetClasses所做的要好得多
List<Student> data = (from student in db.Students
join clss in db.Classes on student.Class equals clss
where student.Name.Contains(search)).ToList()
    int[] Classes = UserDB.GetClasses().Select(c => c.Id).ToArray();

    var items = db.Students.Where(o => o.Name.ToLower().Contains(search))
        .Where(r => Classes.Contains(r.ClassID.Value)).AsQueryable();