解决 EF 分层查询的一个性能问题[转]
前两年帮朋友 做了个网吧管理软件,采用动软的三层架构 sql语句生成的。最近因功能变更 要改动,而我这段正在做asp.net mvc +ef+autofac的一个电商网站。索性 就把原来的底层全重新了套用了我现在的架构 EF6.0+autofac+三层架构,上层的asp.net没有变。改完后发现交班页面打开巨慢。


跟踪EF生成的sql语句 发现生成的sql 有问题,查找的全表,而全表有近10万条的数据。

继续跟踪数据库的耗时查询 发现确实是这条语句占时间


为什么会这样呢,我在查询里做条件搜索了,为啥 结果不对呢?
贴出 BaseRepository.cs 的代码
class="code_img_closed" src="/Upload/Images/2014080923/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('90546e12-ce1e-45ff-857c-4fbf39441633',event)" src="/Upload/Images/2014080923/2B1B950FA3DF188F.gif" alt="" />
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 分层查询的一个性能问题[转]的更多相关文章
- 解决 EF where<T>(func) 查询的一个性能问题
前两年帮朋友 做了个网吧管理软件,采用动软的三层架构 sql语句生成的.最近因功能变更 要改动,而我这段正在做asp.net mvc +ef+autofac的一个电商网站.索性 就把原来的底层全重新了 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (40) ------ 第七章 使用对象服务之从跟踪器中获取实体与从命令行生成模型(想解决EF第一次查询慢的,请阅读)
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-5 从跟踪器中获取实体 问题 你想创建一个扩展方法,从跟踪器中获取实体,用于数 ...
- 第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题
一. 开篇说明 EF的性能问题一直以来经常被人所吐槽,究其原因在于“复杂的操作在生成SQL阶段耗时长,且执行效率不高”,但并不是没有办法解决,从EF本身举几个简单的优化例子: ①:如果仅是查询数据,并 ...
- 讨论过后而引发对EF 6.x和EF Core查询缓存的思考
前言 最近将RabbitMQ正式封装引入到.NET Core 2.0项目当中,之前从未接触过是个高大上的东东跟着老大学习中,其中收获不少,本打算再看看RabbitMQ有时间写写,回来后和何镇汐大哥探讨 ...
- .NET Core使用EF分页查询数据报错:OFFSET语法错误问题
在Asp.Net Core MVC项目中使用EF分页查询数据时遇到一个比较麻烦的问题,系统会报如下错误: 分页查询代码: ) * condition.PageSize).Take(condition. ...
- 匿名类型 使用泛型T linq返回dynamic类型的匿名实体 如何把匿名类型.GetType()返回的对象传进泛型里面 EF实体查询出的数据List<T>转DataTable出现【DataSet 不支持 System.Nullable<>】的问题
[100分]紧急求助:LinQ下使用IQueryable<T>如何将返回类型<T>使用匿名类型 问题描述如下:我有一个方法如下:public IQueryable Dissen ...
- 用EF DataBase First做一个简单的MVC3报名页面
使用EF DataBase First做一个简单的MVC3报名网站 ORM(Object Relational Mapping)是面向对象语言中的一种数据访问技术,在ASP.NET中,可以通过ADO. ...
- EF 数据查询效率对比
优化的地方: 原地址:https://www.cnblogs.com/yaopengfei/p/9226328.html ①:如果仅是查询数据,并不对数据进行增.删.改操作,查询数据的时候可以取消状态 ...
- ASP.NET Core 使用 EF 框架查询数据 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 使用 EF 框架查询数据 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 使用 EF 框架查询数据 上一章节我们学习了如何设置 ...
随机推荐
- 如何使用 require.js ,实现js文件的异步加载,避免网页失去响应,管理模块之间的依赖性,便于代码的编写和维护。
一.为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载.下面的网页代 ...
- Linux 源码的安装 3个步骤
http://www.oseye.net/question/96 源码的安装一般由3个步骤组成:配置(configure).编译(make).安装(make install). Configure是一 ...
- 大数据时代的技术hive:hive的数据类型和数据模型
在上篇文章里,我列举了一个简单的hive操作实例,创建了一张表test,并且向这张表加载了数据,这些操作和关系数据库操作类似,我们常把hive和关系数据库进行比较,也正是因为hive很多知识点和关系数 ...
- gwt 创建 超链接cell (HyperTextCell)
package com.cnblogs.hooligen.client; import com.google.gwt.cell.client.AbstractCell; import com.goog ...
- c#让窗体永在最前 调用windows api 将窗体设为topmost
有时候应用程序需要将一个窗体始终位于屏幕的最前面,即使切换到其它窗体也能看到该窗体,这样的窗体就叫做TopMost窗体. 用C#制作TopMost窗体之前,首先要了解如何声明SetWindowPos函 ...
- jquery delegate
代码如下: $('#container').delegate('a','click',function(){alert('That tickles!')} JQuery扫描文档查找$('#cont ...
- sjtu1313 太湖旅行
Description 西山风景区是苏州著名的国家级风景区,一到暑假,游客们都蜂拥而至.作为太湖风景区的精华,西山景区吸引人的地方主要在它的群岛风光.花果丛林和名胜古迹. ginrat对这个地方向往已 ...
- UVA 11737 Extreme Primitive Society
非常容易的一个题: 只要判断两种基因相差的最小值就行: #include<cstdio> #include<cstring> #include<algorithm> ...
- 对CURL的一些研究
http://www.kuqin.com/article/23candcplusplus/586014.html 前两天看到有人求客户端socket 发HTTP包的代码,受flw版主启发找了一些per ...
- ASP.NET MVC 入门1、简介
什么是MVC模式 MVC(Model-View-Controller,模型-视图-控制器模式)用于表示一种软件架构模式.它把软件系统分为三个基本部分:模型(Model),视图(View)和控制器(Co ...