C#中 EF(EntityFramework) 性能优化

现在工作中很少使用原生的sql了,大多数的时候都在使用EF。刚开始的时候,只是在注重功能的实现,最近一段时间在做服务端接口开发。开发的时候也是像之前一样,键盘噼里啪啦的一顿敲,接口秒秒钟上线,但是到联调测试的时候就悲剧了。。。。那叫一个慢啊,客户端有种“千年等一回的赶脚” 。由于访问量和数量都提升了一个数量级,之前没有 考虑过的问题,都在此时暴露了,根据自己百度、google的经历实践,整理了这一些优化点。欢迎各位大神批评指正!

1.使用AsNoTracking(),无跟踪查询,查询出的数据不可以修改,但是可以提高查询速度

2.合理使用延迟加载。

如果用不到导航属性中的数据,那么使用懒加载就行了,不会加载不需要的数据到内存中。但是,如果会在 foreach 中使用导航属性中的数据,那么最好是禁用懒加载,通过Include()方法,一次加载全部数据,防止在 foreach 多次和数据库进行交互。当然,一般情况下是这样的,具体的还是要根据当时的业务情况而定。

3.判断List中是否含有数据的时候,最好使用Any(),避免使用Count()>0,这么Low的方式,真是慢的一逼啊。

4.在where子句中进行中文字符模糊匹配值的时候,记得加上使用DbFunctions.AsNonUnicode("要匹配的字符")。

5.错误的使用OrderBy() 导致的错误排序。

要对多个字段进行先后组合排序的时候,正确的是Orderby().ThenBy();切记不要这样啊:OrderBy().OrderBy(),这样达不到你想要的效果,只会按照最后的那个排序字段进行排序。

 6.真假分页的问题

line1:query.ToList().Skip((PageIndex - 1) * PageSize).Take(PageSize);

line2: query.Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();

line1就是加分页,直接从DB中取出全部的数据,然后在内存中进行分页;line2才是真正分页。没有ToList()的时候,返回值类型还是IQueryable<T> ,执行了ToList(),之后直接查询数据库了,返回值类型直接是IEnumerable<T>。

7.按需加载部分列。

通过在Select子句中使用select(t=>{t.id,t.name}),只加载需要的列来提升速度。

8.使用扩展库Entity Framework Extendeds 进行批量Insert和delete操作,避免生成大量的sql语句和数据库进行多次交互。

 

9.这些做了,性能还是不行?那SqlQuery(),或者通过储存过程,将多条sql语句作为一个提交单元,也可以减少与数据库的交互次数,从而提高性能。

对于EF首次启动慢的问题,可通过下面的措施进行优化:

1.EF的预热问题,在应用程序进行初始化的时候就事先进行预热。比如,mvc应用程序可在global文件中添加如下操作。

protected void Application_Start()
{
    using (var ctx = new mcccEntities())
    {
        var objectContext = ((IObjectContextAdapter)ctx).ObjectContext;
        var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace);
        mappingCollection.GenerateViews(new List<EdmSchemaError>());
    }

//记得,连接了几个DB就要写几个using啦。

}
原文地址:https://www.cnblogs.com/wangyuliang/p/10338902.html