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

    var str = ''; for(var i = 0;i<data.list.length;i++){ str += "<tr><td>" + (i ...

  2. 去重 取最大的一条sql

    select T.BILL_CODE,t.SCAN_TYPE,t.PIECE,SCAN_SITE,SCAN_MAN, row_number() over(partition by t.bill_cod ...

  3. c/c++编程排坑(1)-- 数据类型的“安静”转换

    这里主要介绍ANSI C的特性:当执行算术运算时,操作数的类型如果不同,就会发生转换.数据类型一般朝着精度更高.长度更长的方向转换,整型数如果转换为signed不会丢失信息,就转换为signed,否则 ...

  4. Navicat for MySQL(Ubuntu)过期解决方法

    推荐购买正版软件,尊重版权  [官网在这里] Navicat for MySQL(Ubuntu系统)免费版试用过期解决方法: Step1. 直接删除 /home目录下的  .navicat文件夹(64 ...

  5. ecshop笔记

    ***ecshop在线入门手册***:http://book.ecmoban.com/ 解决ecshop与jquery冲突问题1.修改文件:/js/transport.js在文件最底部增加代码: if ...

  6. linux whereis-查找二进制程序、代码等相关文件路径

    推荐:更多Linux 文件查找和比较 命令关注:linux命令大全 whereis命令用来定位指令的二进制程序.源代码文件和man手册页等相关文件的路径. whereis命令只能用于程序名的搜索,而且 ...

  7. 转一篇GCC相关的文章

    http://blog.csdn.net/dadoneo/article/details/8201403 Glibc辅助运行库 (C RunTime Library): crt0.o,crt1.o,c ...

  8. BNUOJ 17286 Dollars

    Dollars Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVA. Original ID: 1 ...

  9. [luoguP1433] 吃奶酪(DP || Dfs)

    传送门 深搜加剪纸可A(O(玄学) 1274ms) ——代码 #include <cmath> #include <cstdio> #include <iostream& ...

  10. [fw]Best Practices for Exception Handling

    http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html http://www.onjava.com/pub/a/onjava/200 ...