Entity Framework 6 Recipes 2nd Edition(9-6)译->管理断开时的并发
9-6. 管理断开时的并发
问题
想要确保只接受在WCF客户端并发令牌未被修改的实体。
解决方案
我们有一个如Figure 9-6所示的模型.
Figure 9-6订单实体模型
我们想通过WCF服务来更新一个order ,而要确保这个order 在我们上次取回后没有发生过其它修改。
稍后我们将演示两个不同的方式.两种都用一个TimeStamp列作并发控制。
1. 新建一个WCF服务库,右击解决方案,选择“新建项目”,选择WCF ➤ WCF 服务库,并命名为Recipe6.
2. 右击这个项目,选择“添加” ➤“新建项” ,选择 数据➤ ADO.NET实体数据模型.在向导中选择Order表. 在EF模型设计图中,右击TimeStamp 属性, select “属性“, 把“并发模式”设为Fixed.
3. 用Listing 9-30里的代码定义IService1.cs 文件里的服务
Listing 9-30. Our WCF Service Contract
[ServiceContract]
public interface IService1
{
[OperationContract]
Order InsertOrder();
[OperationContract]
void UpdateOrderWithoutRetrieving(Order order);
[OperationContract]
void UpdateOrderByRetrieving(Order order);
}
4. 用Listing 9-31的代码实现Service1.cs 文件里的服务。
Listing 9-31. The Implementation of Our Service Contract
public class Service1 : IService1
{
public Order InsertOrder()
{
using (var context=new EFRecipesEntities())
{
//删除之前的测试数据
context.Database.ExecuteSqlCommand("delete from chapter9.[order]");
var order = new Order { Product = "Camping Tent", Quantity = 3, Status = "Received" };
context.Orders.Add(order);
context.SaveChanges();
return order;
}
}
public void UpdateOrderWithoutRetrieving(Order order)
{
using (var context=new EFRecipesEntities())
{
try
{
context.Orders.Attach(order);
if (order.Status=="Received")
{
context.Entry(order).Property(x => x.Quantity).IsModified = true;
context.SaveChanges();
}
}
catch (OptimisticConcurrencyException ex)
{
//处理并发异常
}
}
}
public void UpdateOrderByRetrieving(Order order)
{
using (var context=new EFRecipesEntities())
{
//从数据库中获取当前实体
var dbOrder = context.Orders.Single(o => o.OrderId == order.OrderId);
//执行并发检查
if (dbOrder!=null&&StructuralComparisons.StructuralEqualityComparer.Equals(order.TimeStamp,dbOrder.TimeStamp))
{
dbOrder.Quantity = order.Quantity;
context.SaveChanges();
}
else
{
//处理并发问题
}
}
}
}
5. 为测试服务,我们在解决方案里创建一个控制台应用程序.在服务项目上右击,选择“调试” ➤启动新实例,然后在控制项目里添加对这个服务的引用。控制台项目代码如Listing 9-32 所示.
Listing 9-32. The Client We Use to Test Our WCF Service
class Program
{
static void Main(string[] args)
{
var service = new ServiceReference1.Service1Client();
var order = service.InsertOrder();
order.Quantity = 5;
service.UpdateOrderWithoutRetrieving(order);
order = service.InsertOrder();
order.Quantity = 3;
service.UpdateOrderByRetrieving(order);
}
}
如果在Main() 方法前设置断点,逐语句执行,将会看到代码运行入服务端。
它是如何工作的?
InsertOrder() 方法(见Listing 9-31) 删除之前的测试数据,插入一个新的order, 并且返回包含正确ID值和TimeStamp的order.在我们客户端,我们用两个略微不同的方式来更新这个order.
第一种用UpdateOrderWithoutRetrieving()方式:先把从客户端传过来的order 附加Attach()到DbContext,然后判断order状态是否为“Received”,如果是我们把实体 Quantity 属性状态设为 modified然后调用
SaveChanges(). EF会生成一个更新SqL语句,它的Where子句里包含OrderId和TimeStamp.如果SaveChanges()前数据库中该条数据被修改过,则会产生异常(存储区更新、插入或删除语句影响到了意外的行数(0)。实体在加载后可能被修改或删除。刷新 ObjectStateManager 项。)。我们用try,catch来捕获异常. 这样就可以保证客户端提交过来的Order在运行InsertOrder() 之后,数据库里对应记录的数据未被修改过. 其实我们可以在保存前先进行并发检查,从客户端回传的order的TimeStamp属性值与数据库的值比较。这就是UpdateOrderByRetrieving() 方法里采用的方式。
Entity Framework 6 Recipes 2nd Edition(9-6)译->管理断开时的并发的更多相关文章
- Entity Framework 6 Recipes 2nd Edition 译 -> 目录 -持续更新
因为看了<Entity Framework 6 Recipes 2nd Edition>这本书前面8章的翻译,感谢china_fucan. 从第九章开始,我是边看边译的,没有通读,加之英语 ...
- Entity Framework 6 Recipes 2nd Edition(目录索引)
Chapter01. Getting Started with Entity Framework / 实体框架入门 1-1. A Brief Tour of the Entity Framework ...
- Entity Framework 6 Recipes 2nd Edition(9-1)译->用Web Api更新单独分离的实体
第九章 在N层结构的应用程序中使用EF 不是所有的应用都能完全地写入到一个单个的过程中(就是驻留在一个单一的物理层中),实际上,在当今不断发展的网络世界,大量的应用程序的结构包含经典的表现层,应用程, ...
- Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化
9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...
- Entity Framework 6 Recipes 2nd Edition(9-4)译->Web API 的客户端实现修改跟踪
9-4. Web API 的客户端实现修改跟踪 问题 我们想通过客户端更新实体类,调用基于REST的Web API 服务实现把一个对象图的插入.删除和修改等数据库操作.此外, 我们想通过EF6的Cod ...
- Entity Framework 6 Recipes 2nd Edition(13-2)译 -> 用实体键获取一个单独的实体
问题 不管你用DBFirst,ModelFirst或是CodeFirst的方式,你想用实体键获取一个单独的实体.在本例中,我们用CodeFirst的方式. 解决方案 假设你有一个模型表示一个Paint ...
- Entity Framework 6 Recipes 2nd Edition(13-3)译 -> 为一个只读的访问获取实体
问题 你想有效地获取只是用来显示不会更新的操作的实体.另外,你想用CodeFirst的方式来实现 解决方案 一个非常常见行为,尤其是网站,就是只是让用户浏览数据.大多数情况下,用户不会更新数据.在这种 ...
- Entity Framework 6 Recipes 2nd Edition(13-4)译 -> 有效地创建一个搜索查询
问题 你想用LINQ写一个搜索查询,能被转换成更有效率的SQL.另外,你想用EF的CodeFirst方式实现. 解决方案 假设你有如下Figure 13-6所示的模型 Figure 13-6. A s ...
- Entity Framework 6 Recipes 2nd Edition(13-5)译 -> 使POCO的修改追踪更高
问题 你正在使用POCO,你想提高修改跟踪的性能,同时使内存消耗更少.另外,你想通过EF的CodeFirst方式来实现. 解决方案 假设你有一个关于Account(帐户)和相关的Payments(支付 ...
- Entity Framework 6 Recipes 2nd Edition(13-9)译 -> 避免Include
问题 你想不用Include()方法,立即加载一下相关的集合,并想通过EF的CodeFirst方式实现. 解决方案 假设你有一个如Figure 13-14所示的模型: Figure 13-14. A ...
随机推荐
- SQL Server 大数据搬迁之文件组备份还原实战
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 解决方案(Solution) 搬迁步骤(Procedure) 搬迁脚本(SQL Codes) ...
- 干货来袭-整套完整安全的API接口解决方案
在各种手机APP泛滥的现在,背后都有同样泛滥的API接口在支撑,其中鱼龙混杂,直接裸奔的WEB API大量存在,安全性令人堪优 在以前WEB API概念没有很普及的时候,都采用自已定义的接口和结构,对 ...
- Windows Server 2012 NIC Teaming介绍及注意事项
Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...
- 你知道C#中的Lambda表达式的演化过程吗?
那得从很久很久以前说起了,记得那个时候... 懵懂的记得从前有个叫委托的东西是那么的高深难懂. 委托的使用 例一: 什么是委托? 个人理解:用来传递方法的类型.(用来传递数字的类型有int.float ...
- js中参数不对应问题
因为js是一种弱类型的编程语言,对数据类型的要求没有其他编程语言的要求严格,所以在定义函数的时候不需要像java和C#一样对其传入参数的类型进行定义.那么传入参数的个数有没有影响呢?今天小猪就做了个实 ...
- Matlab 高脚杯模型切片
前言:此文为去年我替人做的一个课题,觉得比较简洁,图形也比较美观,因此放在博文里 数据源我放到了百度云盘高脚杯数据源 有兴趣的可以下载数据,跑程序试一下.也可以单独看看代码,看下实现过程. 主函数 % ...
- Android 获取系统相册中的所有图片
Android 提供了API可获取到系统相册中的一些信息,主要还是通过ContentProvider 来获取想要的内容. 代码很简单,只要熟悉ContentProvider 就可以了. public ...
- 香蕉云APP,2016下半年开发日记
2016-6-17 数据库设计不应该过多依赖范式,适度的冗余可以加快搜索速度,在服务器的配置还可以的情况下,可以采用冗余来解决查找慢的问题.还一个是要选择好数据库引擎,例如 InnoDB 和 myi ...
- [开发笔记]yum错误
yum 错误TypeError: rpmdb open failed 解决办法 是因为RPM数据库出现损坏导致的,它导致所有的软件的升级.安装甚至是删除都会出现问题,终端出现乱码,YUMEX也用不成, ...
- 开发者最爱的Firebug停止更新和维护
近日,Firebug团队在其官网上宣布,Firebug将不再继续开发和维护,并邀请大家使用Firefox的内置开发工具. Firebug最初是2006年1月由Joe Hewitt编写, ...