七色花基本权限系统(12)- 优化EntityFramework的配置

EF性能渣?这个锅EF不背

作为ORM,必然有性能上的损失,这是取舍问题。但“舍”的性能损失,大到可以用渣形容吗?

微软在设计EF的时候同时考虑了CS和BS,导致部分配置适合A却不适合B,而可能为了让开发者(无论CS系统开发者还是BS系统开发者)体验到这些配置,默认都是开启的。这直接成为部分开发者认为EF性能很渣的重要原因之一。

这篇日志将粗略介绍几个主要配置的作用和适用场景。

 

最常用的几个主要配置

打开数据库上下文类(MasterEntityContext.cs),该类继承于System.Data.Entity.DbContext,转到其定义,可以看到一个只读属性Configuration,再转到其定义,就可以看到完整的“上下文的配置选项”,一共6个,如下图:

image

 

这6个属性都挺重要的,不需要知道其内部实现,但至少了解作用和适用场景。

 

第一个属性AutoDetectChangesEnabled,表示是否自动追踪数据变化。

举个简单的例子:

  1 var user = db.Users.find(3);
  2 user.Password = "000";
  3 
  4 db.SaveChanges();

以上代码,在SaveChanges时,组装的update语句中,是包含对SysUser的所有属性的update,还是只包含Password属性?

这由配置属性AutoDetectChangesEnabled决定。当该属性是true时,表示自动追踪数据变化,那么在SaveChanges时会自动检测出“哪些属性被修改”,也就能组装出干净的sql语句;而当该属性是false时,表示不追踪数据变化,那么最终的sql语句将包含SysUser所有属性的更改。

image

还有一种更新实体的写法是这样:

  1 var user = db.Users.find(3);
  2 user.Password = "000";
  3 
  4 db.Users.Attach(user);//表示将整个user附加给db,即认为所有属性都是改变了
  5 db.Entry(user).State = System.Data.Entity.EntityState.Modified;

一旦附加,无论AutoDetectChangesEnabled属性是如何设置的,都将在update-sql语句中包含所有属性。

可见AutoDetectChangesEnabled这个属性在BS开发下几乎发挥不了作用,经过http传递的数据在后台接收之后必然是一个新的实体模型对象,需要附加给db,而附加操作就是表示需要对所有属性进行update。

 

第二个属性EnsureTransactionsForFunctionsAndCommands,表示是否应在事务中始终执行 SQL 函数和命令。

EF暴露了直接写sql语句执行的接口,而这个属性就表示在执行这种sql时是否自动嵌套事务。该属性与BS开发并无必然联系,可根据情况开启或关闭,默认是开启的。

 

第三个属性LazyLoadingEnabled,应该和第四个属性ProxyCreationEnabled一起讲。

前者表示是否启用延迟加载,后者表示是否启用代理创建,延迟加载依赖于代理创建。

我们会使用这两个设置来决定是否加载导航属性。默认情况这两个值都是true的,也就是说会以延迟加载的方式加载导航属性,也就是当我们访问导航属性的时候才会去查数据库获取导航属性的数据。

但通常情况下,BS开发时不建议使用ORM的导航属性功能。换句话说就是,不建议为实体之间建立级联关系。

所以这两个属性在BS开发下也是应该关闭的

 

第五个属性UseDatabaseNullSemantics,表示是否展示数据库null语义。

这个跟如何翻译sql有关,比如在mssql中,where A = ‘’和 where A is null 是不同的,因此当linq语句的Where(w => w.A == a)中变量a是null时,就需要告诉EF应该翻译成空呢还是翻译成null还是两者兼顾。这个可根据情况设置。

 

第六个属性ValidateOnSaveEnabled,表示在SaveChanges时是否自动验证实体。

实体类配置中可以对各属性添加验证条件,比如非空、长度限制等。当该属性为true时,会在提交时自动验证。而通常情况下,前端验证加上后端的业务验证,就可以了,数据库级别的验证,交给数据库好了。所以在BS开发下这个属性也可以关闭。

 

这么一来,配置一下以上属性吧。在数据库上下文类(MasterEntityContext)的构造方法中,加上这几句代码:

  1 // 禁用实体状态改变跟踪
  2 Configuration.AutoDetectChangesEnabled = false;
  3 // 禁用导航属性延迟加载
  4 Configuration.LazyLoadingEnabled = false;
  5 // 禁用自动创建代理类
  6 Configuration.ProxyCreationEnabled = false;
  7 // 禁用数据库null语义
  8 Configuration.UseDatabaseNullSemantics = true;
  9 // 禁用保存时验证所跟踪实体
 10 Configuration.ValidateOnSaveEnabled = false;

不过由于该类是T4自动生成的,所以应该把这几句代码加上对应的T4模板中去。

 

简单测试插入万级数据

此处将比较ADO.NET和EF在插入万级别数据时的耗时。

此处直接放测试结果,测试的代码会在源码中。

运行ADO.NET插入10000条用户数据的测试,结果如下图:

image

现在测一下EF插入10000条用户数据的耗时:

image

测试结果也很明显,万条数据插入多700毫秒左右的耗时。中小型系统,基本不必考虑这种万级别的数据插入,即使有也是部分特例。而体量更小的情况下,差距可以基本忽略不计。那么问题只剩下一个:舍弃这部分性能,用来换开发效率是否值得?

 

注:没有把测试代码单独放在单元测试里是因为,在单元测试里测试数据插入,会放大耗时,无论是ADO.NET还是EF,都会被放大70%左右,我也不知道为啥。

 

EF配置相关不是本系列的重点,因此简单带过。

下一章节,将演示业务层的使用以及让数据层与WebUI层解耦。

 

截止本章节,项目源码下载:点击下载(存在百度云盘中)

转载于:https://www.cnblogs.com/matrixkey/p/5629288.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
虎建站最新版 官网 http://74hu.cn 1、后台无法登录,或者网站无法留言 问题:网站能够运行,但后台登录后无法进去管理,或者无法留言,文章内容看不了? 原因:可能是服务器空间有权限问题,无法写入数据。 解决:请与购买商联系。 2、频频出现错误 问题:刚装完程序,网站虽然能够运行,但程序错误频频出现? 原因:可能程序是网友修改过的,也有可能程序版本太旧。 解决:请到官网下载最新的程序,如果没有解决请到官网反馈。 3、网站突发问题 问题:网站平时好好的,近几天突然出现很多的问题? 原因:可能是服务器问题,如网络攻击,也有可能是程序问题,如木马上传。 解决:保留数据库,其他全删掉。到官网下载最新的程序,删掉其中的空数据库,剩下的上传即可。 4、页面自动跳首页 问题:某个页面一点击就自动转到首页? 原因:可能是页面调用出错,系统有错误检查机制,遇到影响系统运行的错误就自动转首页。也有可能是浏览器兼容问题。 解决:仔细检查页面所有内容是否出错。如未能解决问题请到官网求助 5、如何修改管理目录 问题:目前管理地址/admin和/webadmin,容易被人访问 解决:修改管理文件夹的名称,修改db.asp文件,将wapadmin和webadmin对应修改即可,目前支持子目录功能,修改方式相同。 6、系统时间不正确 问题:系统当前时间与实际时间有偏差 原因:空间主机时间错误,或者是使用外国的主机 解决:后台配置-时间配置,输入正确的时间保存即可。系统就会自动修正时间 7、论坛无法管理和会员无法注册 问题:后台管理点击论坛管理出错,前台会员无法注册 原因:国内部分主机有关键词屏蔽 解决:打开config/bbs.asp文件,将bbsagree设定的内容清空,就是改为bbsagree="" 8.游客无法评论文章 问题:游客无法评论文章,总是显示“为提高评论质量,两次评论间隔必须大于10秒!”? 原因:系统时间错误 解决:联系空间购买商,或者启用程序时间修正功能,改系统时间为正确的北京时间。 9.首页空白,后台可以进 问题:系统升级后首页显示空白,但后台可以登录管理 原因:升级步骤出错 解决:按说明文档一步一步操作,升级程序后执行数据库升级补丁updateXXX.asp。如果没有解决请到官网反馈。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值