Entity Framework在Asp.net MVC中的实现One Context Per Request(附源码)

上篇中"Entity Framework中的Identity map和Unit of Work模式", 由于EF中的Identity map和Unit of Work模式,EF体现出来如下特性:

唯一性: 在一个Context的生命周期中,一个Entity只会有一个实例,任何对该实例的修改,即使这些改动没有保存到数据库中,修改都会影响到整个Context的生命周期。

事务性: 所有对于Entity的修改,都会在调用SaveChange方法的时候,一起保存到数据库中,最终实现持久化。

下面基于EF的上面特点,分析一下为什么需要在MVC中实现One Context Per Request, 也就是在一个Request生命周期中,只有一个Context.

阅读目录:

一、每次创建Context的缺点

二、使用全局Context的缺点

三、在MVC中实现One Context Per Request

四、借助Autofac实现One Context Per Request

一,每次创建Context的缺点

一般在项目的数据访问层中使用Entity Framework,代码如下

public IEnumerable<Student> GetStudents()
{ using (var context = new SchoolContext()) { return context.Students.ToList(); } 
}

这个是数据访问层中非常常见的方法,返回DB中所有的Student数据。

这里在使用Context的时候,创建一个Context的实例进行操作。

但是这种方式带来了下面一些缺点:

  • 首先,每次的数据处理,都用new context, 会导致更多的资源开销。
  • 假如业务逻辑层调用GetStudents方法获取到数据之后,要访问Student的导航属性School怎么办? 逻辑层代码使用导航时候就会导致异常,因为EF只能在context生命周期中,才能够再次请求数据库,取得导航属性School的数据。
  • 如果是插入操作,而且是多个关联表的数据插入,插入操作在不同的context中完成,就无法应用EF的事务效果。保证数据能够同时插入成功,如果失败,就一起回滚。
  • 如果在循环中插入数据,每次插入数据都是在不同的context中完成,性能就是一个悲剧。

二,使用全局Context的缺点

看到了"每次创建Context”的缺点,可能会认为使用全局Context是个好的解决方案。

但是全局Context带来的问题更大:

  • 如果全局使用一个Context,会导致越来越多的数据缓存到本地, 随着程序的使用时间越长,占用的资源越来越大。
  • 使用全局Context, 会导致缓存数据无法得到及时更新。即使数据库中的数据有改动,使用EF取出来得数据有可能还是改动之前的数据。

所以:

  • 在MVC项目中,建议每个request, 使用一个Context
  • 在Winform中和WPF中,一个Form或者一个Presenter一个Context
  • 在WebService, Web API中,每次调用, 使用一个Context.

三, 在MVC中实现One Context Per Request

思路是这样的,  在Global.asax.cs文件中,在Begin Request事件中,创建和保存Context; 在End Request事件中,销毁Context. 另外提供一个公开的静态属性来获取这个Context。

详细的代码如下:

在Global.asax.cs中

protected virtual void Application_BeginRequest()
{HttpContext.Current.Items["_EntityContext"] = new EntityContext();
}protected virtual void Application_EndRequest()
{var entityContext = HttpContext.Current.Items["_EntityContext"] as EntityContext;if (entityContext != null)entityContext.Dispose();
}

添加静态属性,以便程序中能够方便的取出和使用Context

public class EntityContext
{public static EntityContext Current{get { return HttpContext.Current.Items["_EntityContext"] as EntityContext; }}
}

四,借助Autofac实现One Context Per Request

Autofac是.net的Ioc容器,具体使用的方法,可以看这里 IoC容器Autofac(4) - Autofact + Asp.net MVC + EF Code First(附源码)

本文的Demo源码,是在上面博客附带的源码基础上修改而来的。

这里,只是介绍一下如何使用Autofac注册Context

在Application_Start函数体内,执行如下代码

var builder = new ContainerBuilder(); //创建builder
//注册builder, 实现one context per request
builder.RegisterType<eassistdevContext>().InstancePerHttpRequest();var container = builder.Build();//创建容器
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));//覆盖MVC默认的实例化Controller的方法,转而又Auotfac容器提供 

更详细的过程,可以在这里直接下载源代码 AutofactMVC(One-Context-Per-Request).zip

源代码中也使用了MiniProfler,推荐一下

转载于:https://www.cnblogs.com/JustRun1983/p/3249462.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/293041.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python随机生成100内的10个整数_用python随机生成数字教程_如何用Python编程随机产生10个随机整数,并输出这10个整数的和�9�3...

如何用Python编程随机产生10个随机整数&#xff0c;并输出这10个整数的和 用Python编程产生10个随机整数&#xff0c;并整数的和&#xff0c;方法如下 准备材料python、电脑 1、需要加载的模块是&#xff1a;random。 2、给出0到10之间的随机整数&#xff1a;import random&…

【linux磁盘分区--格式化】fdisk,parted,mkfs.ext3

磁盘分区完成后&#xff0c;一般就需要对分区进行格式化磁盘分区命令主要有两个&#xff1a;fdisk &#xff1a;最大支持不超过2T分区&#xff1b;parted &#xff1a;支持GPT&#xff0c;适用于大容量分区&#xff1b;分区指令的选择&#xff1a;在RHEL系统上&#xff0c;用fd…

假如人类长出翅膀,会变成这种怪样子

鲁迅曾经说过&#xff1a;“不会画漫画的段子手不是好英语老师”咳咳~ 图图君就是这样一位专注知识科普的双语漫画家长按二维码带你去图图君家串串门儿想知道人类长出翅膀的怪样子吗&#xff1f;长按二维码关注回复“翅膀”寻找答案吧在这里你不仅可以大口呼吸知识还能顺便学个…

CSS3实战开发: 纯CSS实现图片过滤分类显示特效

CSS3实战开发: 纯CSS实现图片过滤分类显示特效 原文:CSS3实战开发: 纯CSS实现图片过滤分类显示特效各位网友大家好&#xff0c;今天我要带领大家开发一个纯CSS的图片分类显示的网址导航&#xff0c;单纯看标题大家可能有些困惑&#xff0c;依照以往惯例&#xff0c;我先给大家演…

Android之Andorid studio 解决Error:Configuration with name ‘default‘ not found

在导入studio工程的时候&#xff0c;进行sync的时候&#xff0c;提示Error:Configuration with name ‘default’ not found. 原因&#xff1a; 打开settings.gradle发现里面有很多个include ‘:app’这样的include&#xff0c;然而发现在工程的目录下面根本没有include的项目…

C# WPF DataGrid获取单元格并改变背景色

01—概述WPF 自带了一个表格控件datagrid&#xff0c;这个控件类似winfrom中的datagridview&#xff0c;在数据显示的时候也经常会用到&#xff0c;这节主要讲解如何从后台代码获取到单元格控件并改变其相关属性&#xff1a;背景色、前景色、字体等。02—效果演示03—代码后台c…

hive集成spark和mysql

参考&#xff1a;http://ihoge.cn/2018/HiveSpark.html 一、Hive安装 1.Hive简介 ​ Hive是Facebook开发的构建于Hadoop集群之上的数据仓库应用&#xff0c;可以将结构化的数据文件映射为一张数据库表&#xff0c;并提供完整的SQL查询功能&#xff0c;可以将SQL语句转换为Ma…

PingingLab传世经典系列《CCNA完全配置宝典》-3.4 Trunk进阶配置

3.4 Trunk进阶配置实验目的&#xff1a;1、掌握Native vlan和Allow vlan的配置。2、理解Native vlan和Allow vlan的功能。实验拓扑&#xff1a;实验步骤&#xff1a;1、依据图中拓扑配置4台主机的IP地址&#xff0c;其中PC通过路由器模拟&#xff0c;配置如下&#xff1a;PC1(c…

python浮点数类型与数学_Python3标准库:decimal定点数和浮点数的数学运算

1. decimal定点数和浮点数的数学运算 decimal模块实现了定点和浮点算术运算&#xff0c;使用的是大多数人所熟悉的模型&#xff0c;而不是程序员熟悉的模式(即大多数计算机硬件实现的IEEE浮点数运算)。Decimal实例可以准确的表示如何数&#xff0c;对其上火其下取整&#xff0c…

业务功能中包含邮件发送,怎么测试?

前言网站开发中&#xff0c;经常碰到需要发送邮件的场景。比如&#xff0c;重置用户密码&#xff0c;需要执行下列流程&#xff1a;用户在重置页面输入邮箱地址进入邮箱&#xff0c;使用获得的重置链接打开重置页面输入新密码一般来说&#xff0c;重置链接都需要包含一个token值…

如何用CSS让一个容器水平垂直居中?

- 第一类&#xff08;被居中的元素有固定的宽高&#xff09; 效果&#xff1a; 第一种方法&#xff08;绝对定位 负margin&#xff09;<div class"div1"> <div class"div2"></div> </div><style type"text/css"&g…

ubuntu设置代理 的三种方式

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程 转载自&#xff1a;http://www.cnblogs.com/lexus/archive/2012/02/20/2359229.html ubuntu下设置代理 2010-01-11 20:13:20| 分类&am…

和男朋友出去玩,该去哪里​?

1 当代熬夜人的脑回路&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼2 确实需要找一下眼珠子&#xff08;via.剪怪不怪&#xff0c;侵删&#xff09;▼3 原来是老师想太多&#xff08;via.万事屋纸纸酱&#xff0c;侵删&#xff09;▼4 有一个会英语的妈妈&#x…

查询表结构的语句总结

四种方式&#xff1a;① DESC 表名② DESCRIBE 表名③ SHOW COLUMNS FROM 表名④ SHOW CREATE TABLE 表名从以上图片结果中可以看出&#xff1a;show columns 和 desc 和 describe 的结果是一样的&#xff0c;即&#xff1a;会将查询的表的每个字段的具体信息列出来,查询的行数…

DB级buffer与IO 查看

--buffer中缓存每个数据库所占的buffer SET TRAN ISOLATION LEVEL READ UNCOMMITTED SELECT ISNULL(DB_NAME(database_id), ResourceDb) AS DatabaseName , CAST(COUNT(row_count) * 8.0 / (1024.0) AS DECIMAL(28,2)) AS [Size (MB)] FROM sys.dm_os_buffer_descriptors…

SparkSQL DataFrame基础篇

SparkSQL DataFrame基础篇 SparkSQL DataFrame进阶篇 SparkSQL DataFrame基础篇 Spark 2.2及以后的SparkSession替换了Spark以前版本中的SparkContext和SQLContext&#xff0c;为Spark集群提供了唯一的入口点。 val spark SparkSession.builder().appName(“SparkExample”)…

ch340串口驱动_关于串口下载问题和超时

串口下载适用于mini、精英、战舰、探索者、阿波罗429不适用于阿波罗767&#xff0c;H743&#xff0c;号令者1052保证板子在独立供电状态下&#xff0c;电源灯处于亮灯状态下&#xff0c;USB线接板子上USB_232&#xff0c;RXD 和 PA9(STM32 的 TXD)TXD 和 PA10(STM32的 RXD)通过…

tcpdump抓取HTTP包

http://blog.csdn.net/kofandlizi/article/details/8106841 cpdump -XvvennSs 0 -i eth0 tcp[20:2]0x4745 or tcp[20:2]0x4854 0x4745 为"GET"前两个字母"GE" 0x4854 为"HTTP"前两个字母"HT" 说明&#xff1a; 通常情况下:一…

cobbler工作流分析

官网 http://cobbler.github.io/ 介绍 Cobbler是一个快速网络安装linux的服务&#xff0c;而且在经过调整也可以支持网络安装windows。该工具使用python开发&#xff0c;小巧轻便&#xff0c;使用简单的命令即可完成PXE网络安装环境的配置&#xff0c;同时还可以管理DHCP、DNS、…

数学到底有多难难难难?看完这个,瞬间觉得智商都提高了!

▲ 点击查看数学家陈省身曾说过&#xff0c;我们每个人一生都花了很多时间学数学&#xff0c;但我们其实只是学会了计算&#xff0c;而不是数学。不知道你有没有听说过这样一句话&#xff1a;想要学好数学&#xff0c;就要靠刷题。尽管我们不得不承认&#xff0c;确实需要不断地…