解决 EF 分层查询的一个性能问题

前两年帮朋友 做了个网吧管理软件,采用动软的三层架构 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     }

调用代码

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     }

同时修改调用代码 为

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<>方法 没问题。但跨了几层传递后 就有问题。并没有生成我想要的查询语句。

解决 EF 分层查询的一个性能问题

时间: 2024-10-25 14:17:49

解决 EF 分层查询的一个性能问题的相关文章

解决 EF 分层查询的一个性能问题[转]

前两年帮朋友 做了个网吧管理软件,采用动软的三层架构 sql语句生成的.最近因功能变更 要改动,而我这段正在做asp.net mvc +ef+autofac的一个电商网站.索性 就把原来的底层全重新了套用了我现在的架构 EF6.0+autofac+三层架构,上层的asp.net没有变.改完后发现交班页面打开巨慢. 跟踪EF生成的sql语句   发现生成的sql 有问题,查找的全表,而全表有近10万条的数据. 继续跟踪数据库的耗时查询 发现确实是这条语句占时间 为什么会这样呢,我在查询里做条件搜索

《Entity Framework 6 Recipes》中文翻译系列 (40) ------ 第七章 使用对象服务之从跟踪器中获取实体与从命令行生成模型(想解决EF第一次查询慢的,请阅读)

翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-5  从跟踪器中获取实体 问题 你想创建一个扩展方法,从跟踪器中获取实体,用于数据保存前执行一些操作. 解决方案 假设你有如图7-7所示的模型. 图7-7. 包含实体Technician和ServiceCall的模型 在这个模型中,每个技术员(technician)都有一些业务服务请求(service call),业务服务请求包含联系人姓名,问题.使用代码清单7-4,创建一个扩展方法获取

第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题

一. 开篇说明 EF的性能问题一直以来经常被人所吐槽,究其原因在于“复杂的操作在生成SQL阶段耗时长,且执行效率不高”,但并不是没有办法解决,从EF本身举几个简单的优化例子: ①:如果仅是查询数据,并不对数据进行增.删.改操作,查询数据的时候可以取消状态追踪. db.TestInfor.AsNoTracking().FirstOrDefault(); ②:用什么查什么,比如一张表有100多个字段,本次业务只需要5个字段,一定是select这5个字段,然后toList,而不是全部查询,再toLis

EF直接查询一张子表的注意事项

项目用到的一个查询,看着再简单不过的查询,没想到居然栽跟头了. 有两张表,一张主表,一张子表[1→多] 在这里我主要是想对子表操作,之所以加主表,是因为在添加子表数据的时候,可以只用一个主表的对象,然后用上下文添加一次,EF自动开存储过程,自动添加关联子表数据.如果大家有什么好的办法让子表一次添加一千多条数据,请指教.[因为我也不太想这样添加数据] 问题就出现在我查询这个子表数据的时候 我的查询语句是这样写的 然后奇迹出现了,按照我的条件约束,查询出来的数据应该只有一两条数据,但是,查询出的结果

讨论过后而引发对EF 6.x和EF Core查询缓存的思考

前言 最近将RabbitMQ正式封装引入到.NET Core 2.0项目当中,之前从未接触过这个高大上的东东跟着老大学习中,其中收获不少,本打算再看看RabbitMQ有时间写写,回来后和何镇汐大哥探讨了一点关于EF和EF Core的内容,于是乎本文就出来了.EF 6.x和EF Core中的查询缓存想必大家都有耳闻或者了解,从数据库中查询出来的实体会形成快照在内存中Copy一份且被上下文跟踪,接下来我们要讲的内容就是这个,我们来看看. EF 6.x和EF Core查询缓存思考 首先我利用EF Co

用EF DataBase First做一个简单的MVC3报名页面

使用EF DataBase First做一个简单的MVC3报名网站 ORM(Object Relational Mapping)是面向对象语言中的一种数据访问技术,在ASP.NET中,可以通过ADO.NET Entity Framework技术来简化数据访问.在EF里,有Code First,Model First和DataBase First三种方法来实现. 百度百科关于ORM的介绍: http://baike.baidu.com/view/197951.htm?fr=aladdin 1.就像

横瓜先生纵论NOSQL与MYSQL实现最热最新查询的分页性能比较

[状元]横瓜-PHP教父(601069289)  20:45:59 大家谈谈NOSQL与MYSQL的差距 NOSQL与MYSQL实现最热最新查询的分页性能比较 MYSQL千亿级要优化的,用起来的不敏捷 如果NOSQL一个语句能搞顶,何必用MYSQL 都没有比较过吗 [状元]Fang(1033289127)  20:46:29 nosql 是 sql 的补充啦 [元帅]IT柏拉图(2500875)  20:46:53 mongodb其实查询上的性能并不会比mysql多太大,只是sock有优势,真正

谈谈如何训练一个性能不错的深度神经网络

谈谈如何训练一个性能不错的深度神经网络 深度学习大火,将各个数据集的state of the art不断地刷新,到了开源代码一放出,有种全民皆可刷排名的节奏. 不过可别把刷数据想的那么简单,不然大家去哪发paper,怎么混饭吃= = 但是我不想发paper就想占坑刷数据怎么办,看到cifar10都尼玛刷到了95%了,我这用caffe自带的小demo才得出78%的结果,caffe你确定不是在骗我? caffe确实没在骗你= =今天我给大家介绍一下如何刷出一个性能接近paper的神经网络 以CNN为

ASP.NET Core 使用 EF 框架查询数据 - ASP.NET Core 基础教程 - 简单教程,简单编程

原文:ASP.NET Core 使用 EF 框架查询数据 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 使用 EF 框架查询数据 上一章节我们学习了如何设置和初始化数据库,以及如何创建迁移代码和应用迁移代码.本章节我们就学习如何使用 EF 框架来查询数据库,至于添加和修改,后面的章节中我们会慢慢学习到 添加测试数据 我们首先使用 SQLite Studio 添加三条数据 ID Name 1 李白 2 杜甫 3 白居易 使用 SQLite Studio