Sar*_*ran 4 asp.net asp.net-mvc entity-framework
我在我的asp.net Web应用程序中使用工作单元和存储库模式以及EF6.每次请求都会创建和销毁DbContext对象.
我认为在每个请求上创建新的dbcontext代价很高(我没有做任何性能基准测试).
是否可以忽略在每个请求上创建DbContext的成本?有人做过一些台架标记吗?
创建一个新的上下文非常便宜,在我的应用程序中平均约为 137 个滴答声(0.0000137 秒)。
另一方面,挂在上下文上可能会非常昂贵,因此请经常处理它。
您查询的对象越多,最终在上下文中跟踪的实体就越多。由于实体是 POCOS,因此实体框架绝对无法知道您修改了哪些实体,只能检查上下文中的每一个实体并进行相应的标记。
当然,一旦它们被标记,它只会对需要更新的那些进行数据库调用,但是当有很多实体被跟踪时,它正在确定哪些需要更新,这是昂贵的,因为它必须根据已知检查所有 POCOS值以查看它们是否已更改。
调用保存更改时的这种更改跟踪非常昂贵,如果您只是一次读取和更新一条记录,则最好在每条记录之后处理上下文并创建一个新记录。另一种方法是挂在上下文上,这样您读取的每条记录都会在上下文中产生一个新实体,并且每次调用 save 更改时,它都会慢一个实体。
是的,它确实更慢。例如,如果您要更新 10,000 个实体,一次将一个实体加载到同一上下文中,则第一次保存将只需要大约 30 个滴答,但随后的每个保存将花费更长的时间,以至于最后一个将花费超过 30,000 个滴答。相比之下,每次创建一个新的上下文将导致每次更新一致的 30 个滴答声。最后,由于挂在上下文和所有被跟踪实体上的累积减慢,在每次提交之前处理和重新创建上下文最终只需要 20% 的时间(总时间的 1/5)!
这就是为什么你真的应该只在上下文中调用一次保存更改,永远,然后处理它。如果您对上下文中的许多实体多次调用保存更改,则您可能没有正确使用它。很明显,特殊情况是当你在做一些事务性的事情时。
如果您需要执行一些事务性操作,那么您需要手动打开您自己的 SqlConnection 并在其上开始一个事务,或者您需要在 TransactionScope 中打开它。然后,您可以通过将相同的打开连接传递给它来创建 DbContext。您可以一遍又一遍地执行此操作,每次处理 DbContext 对象,同时保持连接打开。通常,DbContext 为您处理打开和关闭上下文,但如果您向它传递一个打开的连接,它不会尝试自动关闭它。
这样,您就可以将 DbContext 视为跟踪打开连接上的对象更改的助手。您可以在同一个连接上根据需要多次创建和销毁它,您可以在其中运行您的事务。了解幕后发生的事情非常重要。
实体框架不是线程安全的,这意味着您不能在多个线程中使用上下文.IIS为发送到服务器的每个请求使用一个线程.鉴于此,您必须为每个请求设置一个上下文.否则,您会遇到无法解释和看似随机异常的主要风险,并且可能会将不正确的数据保存到数据库中.
最后,上下文创建并不是一项昂贵的操作.如果您遇到缓慢的应用程序体验(不是在首次启动时,而是在使用该站点之后),您的问题可能就在其他地方.
| 归档时间: |
|
| 查看次数: |
1262 次 |
| 最近记录: |