首先了解一下EF 的几种加载方式
延迟加载(用时加载) 贪婪加载(预先加载) 挑选加载(选列加载) 显示加载
优化的方向:
1:数据库交互次数 2:数据库交互内容 3:查询数据库数据速度 4:本地数据速度 5:大数据批量操作
优化方向1: 数据库交互次数
用到的表最好是一次交互拿出来去使用是最好的,可是当运用延迟加载的时候,用到的时候才会去加载交互数据库,
那么当有循环体中用到了导航属性的表时,就触发了这个条件,每一次循环,都会去加载导航属性的数据,这样次数变多。
优化方案是 关闭延迟加载dbcontext.Configuration.LazyLoadingEnabled = false;
使用include 在循环外 先把导航属性的表内容一次性加载出来 或者是不关闭延迟加载 在循环体外 tolist 放入内存中,不过这种
情况要看数据量的大小,如果导航属性很多且用不到 其实就include 是最好的
优化方向2: 数据库交互内容
项目中用到的数据说白了就是页面上显示的那几十条数据,优化的核心思想就是 快速的找到页面要显示的数据,分页其实是
为了这个服务的,但是真分页才起到了作用,也就是要只查页面数据,不要把所有数据都查出来。其次呢就是要看需要页面的数
据内容存在列多少,如果只是几列内容就不要查整个表中拥有的列,只差所要的列。
那有时候我们页面需要的几个表中不同的一些字段的结合,那这个时候要怎么办,既然是结合版,就不能用原始的model去用来
显示页面内容,那就自定义viewmodel,将这些仅仅需要的结合列,去赋值给viewmodel,然后页面使用。
优化方向3: 查询数据库数据速度
实体状态有5种,Detached分离状态 、Added、 Modified、deleted、Unchanged,增删改查是根据实体状态去判断,通过proxy代理改变跟踪,从而影响数据库 1.只有查询不会对值进行修改删除的话 一定要加上asnotracking 让数据变为分离状态 提高查询速度 2.AsNonUnicode()将输入的字符串视为非 unicode 字符串提高性能 当然如果查询包含中文字符等建议不要使用该方法
一些常用的条件查询方法 1:contains SqlMethods.Like 类似sql中的like 列与列比较 Where(p => SqlMethods.Like(p.Description, "%" + p.Customer.Name + "%")) 本地参数与一列比较 where chosenOnes.Contains(c.Name) 2:take 和skips 取数据排除数据 .Skip (20).Take (20); 3:Distinct 去重复 .Distinct() 4:Any()和count() Any的性能要大于count 而且count和count()的用法不同,context.Post.Count(p => p.Categories.Any(q => q.Name == categoryName)); 这样才能select count(*) 而不是
优化方向4: 本地数据速度
使用linq还是以linq to sql 以IQueryable 的数据源为首,结合数据使用情况 可以使用first(),count(), toarray,tolist,和asenumerable转化成本地数据,然后linq to object进行之后的操作,而AsEnumerable的好处就是延迟执行,并且不会创建任何的存储结构
本地数据也就是内存中的数据,虽然说已经加载到内存当中了,但是查询数据的速度也不同,因为本地数据使用join的查询快得多,因为它的Enumerable实现把内层collection预先装载到一个按键排序的查找器
5:大数据批量操作
禁用自动跟踪变化 DbContext.Configuration.AutoDetectChangesEnabled = false;
每次添加或者删除都会声名状态
使用扩展方法https://blog.youkuaiyun.com/xzwykxz/article/details/52122127