解决 EF whereT(func) 查询的一个性能问题
前两年帮朋友 做了个网吧管理软件,采用动软的三层架构 sql语句生成的。最近因功能变更 要改动,而我这段正在做asp.net mvc +ef+autofac的一个电商网站。索性 就把原来的底层全重新了套用了我现在的架构 EF6.0+autofac+三层架构,上层的asp.net没有变。改完后发现交班页面打开巨慢。
跟踪EF生成的sql语句 发现生成的sql 有问题,查找的全表,而全表有近10万条的数据。
继续跟踪数据库的耗时查询 发现确实是这条语句占时间
为什么会这样呢,我在查询里做条件搜索了,为啥 结果不对呢?
贴出 BaseRepository.cs 的代码
1 public class BaseRepository<T> :IDBbase<T> where T : class 2 { 3 //实例化EF框架 4 protected skdbContext db = new skdbContext(); 5 6 //添加 7 public T AddEntities(T entity) 8 { 9 db.Entry<T>(entity).State = EntityState.Added; 10 db.SaveChanges(); 11 return entity; 12 } 13 14 //修改 15 public bool UpdateEntity(T entity) 16 { 17 db.Set<T>().Attach(entity); 18 db.Entry<T>(entity).State = EntityState.Modified; 19 return db.SaveChanges() > 0; 20 } 21 22 //修改 23 public bool DeleteEntities(T entity) 24 { 25 db.Set<T>().Attach(entity); 26 db.Entry<T>(entity).State = EntityState.Deleted; 27 return db.SaveChanges() > 0; 28 } 29 30 //查询 31 public IQueryable<T> LoadEntities(Func<T, bool> wherelambda) 32 { 33 return db.Set<T>().Where<T>(wherelambda).AsQueryable(); 34 } 35 //查询单个 36 public T LoadEntitie(Func<T, bool> wherelambda) 37 { 38 return db.Set<T>().FirstOrDefault<T>(wherelambda); 39 } 40 41 //分页 42 public IQueryable<T> LoadPagerEntities<S>(int pageSize, int pageIndex, out int total, 43 Func<T, bool> whereLambda, bool isAsc, Func<T, S> orderByLambda) 44 { 45 var tempData = db.Set<T>().Where<T>(whereLambda); 46 47 total = tempData.Count(); 48 49 //排序获取当前页的数据 50 if (isAsc) 51 { 52 tempData = tempData.OrderBy<T, S>(orderByLambda). 53 Skip<T>(pageSize * (pageIndex - 1)). 54 Take<T>(pageSize).AsQueryable(); 55 } 56 else 57 { 58 tempData = tempData.OrderByDescending<T, S>(orderByLambda). 59 Skip<T>(pageSize * (pageIndex - 1)). 60 Take<T>(pageSize).AsQueryable(); 61 } 62 return tempData.AsQueryable(); 63 } 64 }
View Code
调用代码
return jiaobanitem.LoadEntities(t => t.JiaoBanID == jiaobanID && t.GoodsID == GoodsID).FirstOrDefault();
参考 nopCommerce 修改baserepository
1 public class EFRepository<T> : IRepository<T> where T : class 2 { 3 //实例化EF框架 4 //protected YaFeiNetContext db = new YaFeiNetContext(); 5 private DbContext _context; 6 private IDbSet<T> _entities; 7 8 public EFRepository(DbContext context) 9 { 10 this._context = context; 11 } 12 13 14 //添加 15 public virtual T AddEntities(T entity) 16 { 17 try 18 { 19 if(entity==null) 20 throw new ArgumentNullException("entity"); 21 22 this.Entities.Add(entity); 23 this._context.SaveChanges(); 24 return entity; 25 } 26 catch(DbEntityValidationException dbEx) 27 { 28 var msg = string.Empty; 29 foreach(var validationErrors in dbEx.EntityValidationErrors) 30 foreach (var validationError in validationErrors.ValidationErrors) 31 msg += string.Format("Property:{0} Error:{1}", validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine ; 32 33 var fail = new Exception(msg,dbEx); 34 throw fail; 35 } 36 } 37 38 //修改 39 public virtual bool UpdateEntities(T entity) 40 { 41 try 42 { 43 if (entity == null) 44 throw new ArgumentNullException("entity"); 45 46 47 // this.Entities.Attach(entity); 48 // _context.Entry<T>(entity).State = EntityState.Modified; 49 return this._context.SaveChanges() > 0; 50 } 51 catch (DbEntityValidationException dbEx) 52 { 53 var msg = string.Empty; 54 foreach (var validationErrors in dbEx.EntityValidationErrors) 55 foreach (var validationError in validationErrors.ValidationErrors) 56 msg += string.Format("Property:{0} Error:{1}", validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine; 57 58 var fail = new Exception(msg, dbEx); 59 throw fail; 60 } 61 62 } 63 64 //修改 65 public virtual bool DeleteEntities(T entity) 66 { 67 try 68 { 69 if (entity == null) 70 throw new ArgumentNullException("entity"); 71 72 //db2.Set<T>().Attach(entity); 73 //db2.Entry<T>(entity).State = EntityState.Deleted; 74 this.Entities.Remove(entity); 75 return this._context.SaveChanges() > 0; 76 } 77 catch (DbEntityValidationException dbEx) 78 { 79 var msg = string.Empty; 80 foreach (var validationErrors in dbEx.EntityValidationErrors) 81 foreach (var validationError in validationErrors.ValidationErrors) 82 msg += string.Format("Property:{0} Error:{1}", validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine; 83 84 var fail = new Exception(msg, dbEx); 85 throw fail; 86 } 87 88 89 } 90 91 //查询 92 public virtual IQueryable<T> LoadEntities(Func<T, bool> wherelambda) 93 { 94 return this.Entities.Where<T>(wherelambda).AsQueryable(); 95 } 96 //查询单个 97 public virtual T LoadEntitie(Func<T, bool> wherelambda) 98 { 99 return this.Table.Where(wherelambda).FirstOrDefault(); 100 } 101 /// <summary> 102 /// 根据主键查找 103 /// </summary> 104 /// <param name="id"></param> 105 /// <returns></returns> 106 public virtual T GetById(object id) 107 { 108 return this.Entities.Find(id); 109 } 110 111 112 113 114 //分页 115 public virtual IQueryable<T> LoadPagerEntities<S>(int pageSize, int pageIndex, out int total, 116 Func<T, bool> whereLambda, bool isAsc, Func<T, S> orderByLambda) 117 { 118 119 var tempData = this.Entities.Where<T>(whereLambda); 120 121 total = tempData.Count(); 122 123 //排序获取当前页的数据 124 if (isAsc) 125 { 126 tempData = tempData.OrderBy<T, S>(orderByLambda). 127 Skip<T>(pageSize * (pageIndex - 1)). 128 Take<T>(pageSize).AsQueryable(); 129 } 130 else 131 { 132 tempData = tempData.OrderByDescending<T, S>(orderByLambda). 133 Skip<T>(pageSize * (pageIndex - 1)). 134 Take<T>(pageSize).AsQueryable(); 135 } 136 return tempData.AsQueryable(); 137 138 139 140 } 141 142 protected virtual IDbSet<T> Entities 143 { 144 get 145 { 146 if (_entities == null) 147 _entities = _context.Set<T>(); 148 return _entities; 149 } 150 } 151 152 153 public virtual IQueryable<T> Table 154 { 155 get { return this.Entities; } 156 } 157 158 159 }
View Code
同时修改调用代码 为
return jiaobanitem.Table.Where(t=>t.JiaoBanID ==jiaobanID && t.GoodsID ==GoodsID).FirstOrDefault();
问题解决 页面响应不到100ms 同时调试中 生成的sql语句已经有 查询条件了
问题出在
//查询
public IQueryable<T> LoadEntities(Func<T, bool> wherelambda)
{
return db.Set<T>().Where<T>(wherelambda).AsQueryable();
}
为了验证,我在前台直接调用
return this.context.Set<tb_e_jiaoBanItem>().Where(t => t.JiaoBanID == jiaobanID && t.GoodsID == GoodsID).AsQueryable().FirstOrDefault();
页面响应也是 100ms左右,性能没问题。直接调用 dbcontext的set<>方法 没问题。但跨了几层传递后 就有问题。并没有生成我想要的查询语句。
这个问题原来别人也碰到过 http://www.cnblogs.com/yjmyzz/archive/2008/09/06/1285564.html
如果传入Where的参数为Expression,则L2S会自动帮忙处理Expression的拼接;而如果传入的是Func,而L2S无法拼接Expression与Func,所以只好先把数据全部取出来,然后再应用Func来进行数据过滤。
代码应该修改为:
public virtual IEnumerable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T,bool>> wherelambda)
{
return this.Table.Where<T>(wherelambda);
}
转载于:https://www.cnblogs.com/xiaokangufo/p/3901402.html
解决 EF whereT(func) 查询的一个性能问题相关推荐
- 第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题
一. 开篇说明 EF的性能问题一直以来经常被人所吐槽,究其原因在于"复杂的操作在生成SQL阶段耗时长,且执行效率不高",但并不是没有办法解决,从EF本身举几个简单的优化例子: ①: ...
- EF提示一例对一个或多个实体的验证失败。有关详细信息,请参阅“EntityValidationErrors”属性的解决
EF提示一例对一个或多个实体的验证失败.有关详细信息,请参阅"EntityValidationErrors"属性的解决 在向数据库添加数据时出现该错误. 对出先错误的语句进行try ...
- AutoDetectChangesEnabled及AddRange解决EF插入的性能问题
AutoDetectChangesEnabled及AddRange解决EF插入的性能问题 参考文章: (1)AutoDetectChangesEnabled及AddRange解决EF插入的性能问题 ( ...
- 微服务架构下,解决数据库跨库查询的一些思路
开局先总结一下:现在很多厂都进行了微服务的开发模式,但是呢,业务的拆分的时候如果存在交叉是一件非常头大的事情,所以大家写微服务尽量不要交叉的写,比如新增用户如果已经存在在userservice里面了那 ...
- java hive查询_java程序调用hive查询的一个异常
最近在java程序中调用hive做查询时,碰到一个异常,被困扰了许久,经过几番调试,逐步把问题定位清楚. 在异常描述前先给出异常信息:java.sql.SQLException: Error whil ...
- mysql分页总页数算法解析_详解MySQL的limit用法和分页查询语句的性能分析
limit用法 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能. SELECT * FROM table LIMIT ...
- [翻译 EF Core in Action 2.3] 理解EF Core数据库查询
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- Oracle数据库的并行查询,解决Oracle数据库并行查询出错的方法
当我们在使用Oracle数据库的时候会发现Oracle数据库并行查询出错这一问题,那么你知道如何解决Oracle数据库并行查询出错吗?下面就是解决Oracle数据库并行查询出错的方法介绍. Oracl ...
- EF跨库查询,DataBaseFirst下的解决方案
EF跨库查询,DataBaseFirst下的解决方案 参考文章: (1)EF跨库查询,DataBaseFirst下的解决方案 (2)https://www.cnblogs.com/zyug/p/586 ...
最新文章
- 在网页中加入百度搜索条
- Java设计模式(四):工厂设计模式
- java生成密码_java生成密码生成 | 学步园
- 呼吁开放外网_服装数据集:呼吁采取行动
- Zabbix监控Dell服务器主机和网络设备
- c语言程序设计逗号作用,逗号运算符C语言程序设计.pdf
- NET USE 命令用法
- easymock使用方法_EasyMock最终方法– PowerMock,JUnit 4,TestNG
- php中合并数组保留键值,如何使用php合并数组并保留键值的方法
- 数据库 chapter 10 数据库恢复技术
- 个人财务管理系统mysql_开发个人财务管理系统(一)建数据库
- 复盘模型_如何运用MT4软件进行复盘,提高水平
- 知识图谱05:知识图谱构建涉及的技术
- K-Means算法与FCM算法
- Oracle数据库PL/SQL块-存储函数和过程
- 能够翻译文档的免费软件-免费翻译整个文档的软件
- 关于微软IIS7安全性
- mysql转化为GaussDB_gaussDB数据库常用操作命令
- 基于rt-thread的udp客户端
- JavaScript整合版——后端程序员学js,只读一文直接零基础入门,大学生期末考试不挂科宝典。