C# 实体框架在添加“where子句”时花费太多时间
我正在研究学校系统,这个系统有很多用户窃取者和管理者 工具 Asp.net 5 MVC与C VS 2015 SQL SERVER Azure 代码优先方法 分配给一个或多个类的每个用户 用户应该只看到他的类和类内的学生 在另一边 捕捉每个用户类 我写过这个方法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()
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();