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

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

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

为什么会这样呢,我在查询里做条件搜索了,为啥 结果不对呢?

贴出 BaseRepository.cs 的代码

 public class BaseRepository<T> :IDBbase<T>  where T : class
{
//实例化EF框架
protected skdbContext db = new skdbContext(); //添加
public T AddEntities(T entity)
{
db.Entry<T>(entity).State = EntityState.Added;
db.SaveChanges();
return entity;
} //修改
public bool UpdateEntity(T entity)
{
db.Set<T>().Attach(entity);
db.Entry<T>(entity).State = EntityState.Modified;
return db.SaveChanges() > ;
} //修改
public bool DeleteEntities(T entity)
{
db.Set<T>().Attach(entity);
db.Entry<T>(entity).State = EntityState.Deleted;
return db.SaveChanges() > ;
} //查询
public IQueryable<T> LoadEntities(Func<T, bool> wherelambda)
{
return db.Set<T>().Where<T>(wherelambda).AsQueryable();
}
//查询单个
public T LoadEntitie(Func<T, bool> wherelambda)
{
return db.Set<T>().FirstOrDefault<T>(wherelambda);
} //分页
public IQueryable<T> LoadPagerEntities<S>(int pageSize, int pageIndex, out int total,
Func<T, bool> whereLambda, bool isAsc, Func<T, S> orderByLambda)
{
var tempData = db.Set<T>().Where<T>(whereLambda); total = tempData.Count(); //排序获取当前页的数据
if (isAsc)
{
tempData = tempData.OrderBy<T, S>(orderByLambda).
Skip<T>(pageSize * (pageIndex - )).
Take<T>(pageSize).AsQueryable();
}
else
{
tempData = tempData.OrderByDescending<T, S>(orderByLambda).
Skip<T>(pageSize * (pageIndex - )).
Take<T>(pageSize).AsQueryable();
}
return tempData.AsQueryable();
}
}

调用代码

return jiaobanitem.LoadEntities(t => t.JiaoBanID == jiaobanID && t.GoodsID == GoodsID).FirstOrDefault();

参考 nopCommerce  修改baserepository

 public class EFRepository<T> : IRepository<T> where T : class
{
//实例化EF框架
//protected YaFeiNetContext db = new YaFeiNetContext();
private DbContext _context;
private IDbSet<T> _entities; public EFRepository(DbContext context)
{
this._context = context;
} //添加
public virtual T AddEntities(T entity)
{
try
{
if(entity==null)
throw new ArgumentNullException("entity"); this.Entities.Add(entity);
this._context.SaveChanges();
return entity;
}
catch(DbEntityValidationException dbEx)
{
var msg = string.Empty;
foreach(var validationErrors in dbEx.EntityValidationErrors)
foreach (var validationError in validationErrors.ValidationErrors)
msg += string.Format("Property:{0} Error:{1}", validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine ; var fail = new Exception(msg,dbEx);
throw fail;
}
} //修改
public virtual bool UpdateEntities(T entity)
{
try
{
if (entity == null)
throw new ArgumentNullException("entity"); // this.Entities.Attach(entity);
// _context.Entry<T>(entity).State = EntityState.Modified;
return this._context.SaveChanges() > ;
}
catch (DbEntityValidationException dbEx)
{
var msg = string.Empty;
foreach (var validationErrors in dbEx.EntityValidationErrors)
foreach (var validationError in validationErrors.ValidationErrors)
msg += string.Format("Property:{0} Error:{1}", validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine; var fail = new Exception(msg, dbEx);
throw fail;
} } //修改
public virtual bool DeleteEntities(T entity)
{
try
{
if (entity == null)
throw new ArgumentNullException("entity"); //db2.Set<T>().Attach(entity);
//db2.Entry<T>(entity).State = EntityState.Deleted;
this.Entities.Remove(entity);
return this._context.SaveChanges() > ;
}
catch (DbEntityValidationException dbEx)
{
var msg = string.Empty;
foreach (var validationErrors in dbEx.EntityValidationErrors)
foreach (var validationError in validationErrors.ValidationErrors)
msg += string.Format("Property:{0} Error:{1}", validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine; var fail = new Exception(msg, dbEx);
throw fail;
} } //查询
public virtual IQueryable<T> LoadEntities(Func<T, bool> wherelambda)
{
return this.Entities.Where<T>(wherelambda).AsQueryable();
}
//查询单个
public virtual T LoadEntitie(Func<T, bool> wherelambda)
{
return this.Table.Where(wherelambda).FirstOrDefault();
}
/// <summary>
/// 根据主键查找
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual T GetById(object id)
{
return this.Entities.Find(id);
} //分页
public virtual IQueryable<T> LoadPagerEntities<S>(int pageSize, int pageIndex, out int total,
Func<T, bool> whereLambda, bool isAsc, Func<T, S> orderByLambda)
{ var tempData = this.Entities.Where<T>(whereLambda); total = tempData.Count(); //排序获取当前页的数据
if (isAsc)
{
tempData = tempData.OrderBy<T, S>(orderByLambda).
Skip<T>(pageSize * (pageIndex - )).
Take<T>(pageSize).AsQueryable();
}
else
{
tempData = tempData.OrderByDescending<T, S>(orderByLambda).
Skip<T>(pageSize * (pageIndex - )).
Take<T>(pageSize).AsQueryable();
}
return tempData.AsQueryable(); } protected virtual IDbSet<T> Entities
{
get
{
if (_entities == null)
_entities = _context.Set<T>();
return _entities;
}
} public virtual IQueryable<T> Table
{
get { return this.Entities; }
} }

同时修改调用代码 为

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);
}

解决 EF where<T>(func) 查询的一个性能问题的更多相关文章

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

    前两年帮朋友 做了个网吧管理软件,采用动软的三层架构 sql语句生成的.最近因功能变更 要改动,而我这段正在做asp.net mvc +ef+autofac的一个电商网站.索性 就把原来的底层全重新了 ...

  2. 深入理解 EF Core:使用查询过滤器实现数据软删除

    原文:https://bit.ly/2Cy3J5f 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能会去除一些本人实在不知道如何组织 ...

  3. 疑难杂症——EF+Automapper引发的查询效率问题解析

    前言:前面总结了一些WebApi里面常见问题的解决方案,本来打算来分享下oData+WebApi的使用方式的,奈何被工作所困,只能将此往后推了.今天先来看看EF和AutoMapper联合使用的一个问题 ...

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

    一. 开篇说明 EF的性能问题一直以来经常被人所吐槽,究其原因在于“复杂的操作在生成SQL阶段耗时长,且执行效率不高”,但并不是没有办法解决,从EF本身举几个简单的优化例子: ①:如果仅是查询数据,并 ...

  5. 解决EF没有生成字段和表说明

    找了很多资料,终于找到一篇真正能解决ef生成字段说明,注释的文章,收藏不了,于是转载 本文章为转载,原文地址 项目中使用了EF框架,使用的是Database-First方式,因为数据库已经存在,所以采 ...

  6. mysql根据逗号分割的字符串去关联查询另外一个表的数据

    1.说明 在做显示数据的时候,一个字段会存那种逗号分割的字符串,那如何去根据逗号分割字符串去查询另一个表的数据呢? 首先我们查看一下需要显示的数据 select * from company wher ...

  7. EF Core 的关联查询

    0 前言 本文会列举出 EF Core 关联查询的方法: 在第一.二.三节中,介绍的是 EF Core 的基本能力,在实体中配置好关系,即可使用,且其使用方式,与编程思维吻合,是本文推荐的方式. 第四 ...

  8. MySQL GROUP_CONCAT函数使用示例:如何用一个SQL查询出一个班级各个学科第N名是谁?

    如何用一个SQL查询出一个班级各个学科第N名是谁? 首先贴出建表语句,方便大家本地测试: -- 建表语句 CREATE TABLE score ( id INT NOT NULL auto_incre ...

  9. Oracle一个用户查询另一个用户的表数据

    1.两个用户是在不同的库,需要建立dblink 2.属于同一个库的不同用户 1)方法一:使用"用户名."的方式访问 例如:要从USER1账号访问USER2中的表TABLE2 A. ...

随机推荐

  1. adb 命令收藏学习地址

    adb 命令相关的网页https://www.cnblogs.com/medsonk/p/8334847.htmlhttps://www.cnblogs.com/medsonk/p/6959658.h ...

  2. Spring资源访问接口Resource

    该接口拥有对不同资源类型的实现类 boolean exists() 资源是否存在 boolean isOpen() 资源是否打开 URL getURL() 如果底层资源可以表示成URL,则该方法返回对 ...

  3. linux ltrace-跟踪进程调用库函数的情况

    当前位置:硬件 | 监测 | 内核 | Shell / 性能监测与优化 /ltrace ltrace命令是用来跟踪进程调用库函数的情况. 语法 ltrace [option ...] [command ...

  4. ZJU cluster

    * loginSSH using MobaXterm: >> ssh kaiming@10.106.239.105

  5. [转] angular2+highcharts+chart.js

    这里是在ionic2下使用highchairs和chart.js的简单示例chartjs部分参考http://www.jianshu.com/p/bc18132da812 1.安装hightchart ...

  6. hdu 4670 树的分治-求点对的个数

    /* 树的分治 因为树的点权值可达到10^15,注意手动扩栈,还有int64 题意:给你一棵树,给你一些素数,给你每个点一个权值且每个权值均可由这些素数组成.现在定义任意任意两点的价值为他们路径上的权 ...

  7. HTTP Simple Storage

    ubuntu12.10桌面版 1.安装FastCGI /usr/bin/spawn-fcgi这个文件来管理 FastCGI,它原属于lighttpd这个包里面,但 9.10 后,spawn-fcgi被 ...

  8. VScode输出中文乱码的解决方法------测试过可以用

    用python写个爬虫,配置个VScode环境,发现输出都是乱码,翻阅网站后发现一个简单有效的方法,在此谢过网络上的大牛们的无私分享,我也在此记录一下,以备后用: 文件---->首选项----& ...

  9. ECMAScript 6 入门学习笔记(二)——变量的解构赋值

    一.数组的解构赋值 let [foo, [[bar], baz]] = [1, [[2], 3]]; ①可多不可少,等号的右边是数组 let [x, y] = [1, 2, 3]; //可以 let ...

  10. PHP与WCF第一次亲密接触

    接触PHP第二天,要求PHP访问WCF服务 着实痛苦,无从下手啊. 在网上查了很多资料知道PHP访问WCF很方便 <?php $client = new SoapClient ( 'http:/ ...