EntityFramwork--处理数据并发问题时支持乐观并发,即假定最佳场景(这里是指数据在更新过程中没有发生变化)

具体看《Beginning ASP.NET 4.5 Databases》P188-189:

本书源代码下载地址:

http://www.codeplex.com/Download?ProjectName=CommonServiceLocator&DownloadId=45067

以一下是截取源代码的实现Unit of work、并发、事务的BaseRepository:

BaseRepository.cs:

 using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using Repository; namespace DataAccess
{
public class s : IDisposable
{
protected IUnitOfWork UnitOfWork { get; set; }
private bool disposed = false; protected StoreEntities Context
{
get { return (EfStoreDataContext)this.UnitOfWork; }
} /// <summary>
/// .ctor
/// </summary>
/// <param name="unitOfWork"></param>
public BaseRepository(IUnitOfWork unitOfWork)
{
if (unitOfWork == null) throw new ArgumentNullException("unitOfWork");
this.UnitOfWork = unitOfWork;
} public void Save()
{
try
{
using(var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
this.Context.SaveChanges();
scope.Complete();
}
}
catch (DbUpdateConcurrencyException concurrencyException)
{
concurrencyException.Entries.Single().OriginalValues.SetValues(concurrencyException.Entries.Single().GetDatabaseValues());
throw;
}
} protected virtual DbSet<TEntity> GetDbSet<TEntity>() where TEntity : class
{
return this.Context.Set<TEntity>();
} protected virtual void SetEntityState(object entity, EntityState entityState)
{
this.Context.Entry(entity).State = entityState;
} protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
this.Context.Dispose();
}
}
this.disposed = true;
} public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
---------------------------
(一).事务
38                 using(var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
39 {
40 this.Context.SaveChanges();
41 scope.Complete();
42 }
使用事务的目的:在某个场景中,需要更新多个数据上下文实例,并想要把这些更新放在一个事务中。

2.

---------------
(二)并发
44             catch (DbUpdateConcurrencyException concurrencyException)
45 {
46 concurrencyException.Entries.Single().OriginalValues.SetValues(concurrencyException.Entries.Single().GetDatabaseValues());
47 throw;
48 }
 
EF框架处理并发的方式:
方式1:
让客户端决定状态----让项的原始值设置为从数据库中获取的值:
concurrencyException.Entries.Single().OriginalValues.SetValues(concurrencyException.Entries.Single().GetDatabaseValues());
方式2:
让客户端决定状态----用存储中的值刷新新实体值:
concurrencyException.Entries.Single().Reload();

方式3:
自定义一种方案,选择合适的选项。 ---------------------
(三)工作单元 Unit of work
EF中的Unit Of Work机制
(假设StoreEntities 实例的变量名为contexDb)
contexDb.Entry(Order).State = System.Data.EntityState.Modified; //
------------------------------------------------
下面代码是设计一个实现了Unit of work机制和Repository模式的具体实现:
56         protected virtual void SetEntityState(object entity, EntityState entityState)
57 {
58 this.Context.Entry(entity).State = entityState;
59 }

this.Context是
19         protected StoreEntities Context
20 {
21 get { return (EfStoreDataContext)this.UnitOfWork; }
22 }
EfStoreDataContext.cs
     public class EfStoreDataContext : StoreEntities, IUnitOfWork
{
public new void SaveChanges()
{
base.SaveChanges();
}
}

EF生成的访问数据的DbContext

 namespace DataAccess
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using Entities; public partial class StoreEntities : DbContext
{
public StoreEntities()
: base("name=StoreEntities")
{
} protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
} public DbSet<Contact> Contacts { get; set; }
public DbSet<Order> Orders { get; set; }
}
}

IUnitofWork.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Repository
{
public interface IUnitOfWork
{
void SaveChanges();
}
}
使用了工作单元 (Unit of work)机制的OrderReposiory:
OrderReposiory.cs:
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Entities;
using Repository; namespace DataAccess.Repositories
{
public class OrderRepository : BaseRepository, IOrderRepository
{ public OrderRepository(IUnitOfWork unitOfWork)
: base(unitOfWork)
{ } public IEnumerable<Order> GetAllOrders()
{
return this.GetDbSet<Order>();
} public Order GetByOrderId(int orderId)
{
return this.GetDbSet<Order>().Find(orderId);
} public void Create(Order order)
{
this.GetDbSet<Order>().Add(order);
} public void Update(Order order)
{
this.SetEntityState(order, System.Data.EntityState.Modified);
} public void Delete(int orderId)
{
var order = this.GetDbSet<Order>().Find(orderId);
this.GetDbSet<Order>().Remove(order);
}
}
}
根据上面的设计,这行代码:
37             this.SetEntityState(order, System.Data.EntityState.Modified);
最终调用EF框架生成的
  public partial class StoreEntities : DbContext
的方法
contexDb.Entry(Order).State = System.Data.EntityState.Modified; //EF中的Unit Of Work机制
假设StoreEntities 实例的变量名为contexDb



 
 

【EntityFramwork--处理数据并发问题】的更多相关文章

  1. python导出zabbix数据并发邮件脚本

    Zabbix没有报表导出的功能,于是通过编写脚本导出zabbix数据并发邮件.效果如下: 下面是脚本,可根据自己的具体情况修改: #!/usr/bin/python #coding:utf-8 imp ...

  2. EF|CodeFirst数据并发管理

    在项目开发中,我们有时需要对数据并发请求进行处理.举个简单的例子,比如接单系统中,AB两个客服同时请求处理同一单时,应该只有一单请求是处理成功的,另外一单应当提示客服,此单已经被处理了,不需要再处理. ...

  3. Oracle的数据并发与一致性详解(下)

    上篇介绍了数据并发与一致性的相关概念.以及oracle的事务隔离级别等内容,本篇继续介绍锁机制.自动锁.手动锁.用户自定义锁的相关内容. 请尊重作者劳动成果,转载请标明原文链接: https://ww ...

  4. Oracle的数据并发与一致性详解(上)

    今天想了解下oracle中事务与锁的原理,但百度了半天,发现网上介绍的内容要么太短,要么版本太旧,而且抄袭现象严重,所以干脆查官方帮助文档(oracle 11.2),并将其精华整理成中文,供大家一起学 ...

  5. js获取cookie数据并发送给服务端

    js获取cookie数据并发送给服务端 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...

  6. ADO.NET 中的数据并发

    当多个用户试图同时修改数据时,需要建立控制机制来防止一个用户的修改对同时操作的其他用户所作的修改产生不利的影响.处理这种情况的系统叫做“并发控制”.并发控制的类型通常,管理数据库中的并发有三种常见的方 ...

  7. sqlserver用timestamp帮助解决数据并发冲突 转【转】

    http://blog.csdn.net/u011014032/article/details/42936783 关于并发请求,网上很多朋友都说的很详细了,我就不在这里献丑了.这里只记录下刚刚完工的那 ...

  8. Entity Framework 数据并发访问错误原因分析与系统架构优化

    博客地址 http://blog.csdn.net/foxdave 本文主要记录近两天针对项目发生的数据访问问题的分析研究过程与系统架构优化,我喜欢说通俗的白话,高手轻拍 1. 发现问题 系统新模块上 ...

  9. html 获取数据并发送给后端方式

    一.方式一 使用ajax提交 function detailed() { var date = $("#asset_ip").text() $.ajax({ url: " ...

随机推荐

  1. UI1_应用的程序的生命周期

    // // AppDelegate.m // UI1_应用的程序的生命周期 // // Created by zhangxueming on 15/6/29. // Copyright (c) 201 ...

  2. fread 和 fwrite 函数用法示例以及注意事项

    1.函数功能   用来读写一个数据块. 2.一般调用形式   fread(buffer,size,count,fp);   fwrite(buffer,size,count,fp); 3.说明   ( ...

  3. java面试题小全

    面向对象的特征有哪些方面   1. 抽象:抽象就是忽略一个主题中与当前目标2. 无关的那些方面,3. 以便更充分地注意与当前目标4. 有关的方面.抽象并不5. 打算了解全部问题,而6. 只是选择其中的 ...

  4. javascript构造函数小记

    function outer(){ function inner(){} return inner; } var a=outer(); var b=outer(); var c=new outer() ...

  5. ArcGIS 坐标系统文件

    坐标是GIS数据的骨骼框架,能够将我们的数据定位到相应的位置,为地图中的每一点提供准确的坐标. ArcGIS自带了多种坐标系统,在${ArcGISHome}Coordinate Systems目录下可 ...

  6. 特殊的attribute机制

    __attribute__机制是GNU C的一大特色,可以用来设置函数,变量和数据类型的属性,下面对工作中正好用到的两个属性做下简单介绍. 1. constructor 这个属性指定函数在main函数 ...

  7. 【MediaKit】WPF项目中 调用摄像头拍照的开发包

    今天遇到一个 人事的项目,项目中需要调用摄像头给员工照相.如何解决这个问题呢? 介绍一个开发包给你,MediaKit.论坛里头的人都说好,但是黑兔觉得大家好才是真的好.你不妨试试~ 第一步:添加WPF ...

  8. Java HttpURLConnection 抓取网页内容 解析gzip格式输入流数据并转换为String格式字符串

    最近GFW为了刷存在感,搞得大家是头晕眼花,修改hosts 几乎成了每日必备工作. 索性写了一个小程序,给办公室的同事们分享,其中有个内容 就是抓取网络上的hosts,废了一些周折. 我是在一个博客上 ...

  9. java web 路径 --转载

    主题:java(Web)中相对路径,绝对路径问题总结 1.基本概念的理解 绝对路径:绝对路径就是你的主页上的文件或目录在硬盘上真正的路径,(URL和物理路径)例如:C:\xyz\test.txt 代表 ...

  10. ros-Qt代码环境的搭建

    1 建立package catkin_create_pkg beginner_tutorials roscpp 2 导入Qt Qt中打开整个工作空间的src/CMakeLists.txt 在倒数第二行 ...