【EntityFramwork--处理数据并发问题】

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

 

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

 

 

 

本书源代码下载地址:

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

 

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

BaseRepository.cs:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Data;
 4 using System.Data.Entity;
 5 using System.Data.Entity.Infrastructure;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Threading.Tasks;
 9 using System.Transactions;
10 using Repository;
11 
12 namespace DataAccess
13 {
14     public class s : IDisposable
15     {
16         protected IUnitOfWork UnitOfWork { get; set; }
17         private bool disposed = false;
18 
19         protected StoreEntities Context
20         {
21             get { return (EfStoreDataContext)this.UnitOfWork; }
22         }
23 
24         /// <summary>
25         /// .ctor
26         /// </summary>
27         /// <param name="unitOfWork"></param>
28         public BaseRepository(IUnitOfWork unitOfWork)
29         {
30             if (unitOfWork == null) throw new ArgumentNullException("unitOfWork");
31             this.UnitOfWork = unitOfWork;
32         }
33 
34         public void Save()
35         {
36             try
37             {
38                 using(var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
39                 {
40                     this.Context.SaveChanges();
41                     scope.Complete();
42                 }
43             }
44             catch (DbUpdateConcurrencyException concurrencyException)
45             {
46                 concurrencyException.Entries.Single().OriginalValues.SetValues(concurrencyException.Entries.Single().GetDatabaseValues());
47                 throw;
48             }
49         }
50 
51         protected virtual DbSet<TEntity> GetDbSet<TEntity>() where TEntity : class
52         {
53             return this.Context.Set<TEntity>();
54         }
55 
56         protected virtual void SetEntityState(object entity, EntityState entityState)
57         {
58             this.Context.Entry(entity).State = entityState;
59         }
60 
61         protected virtual void Dispose(bool disposing)
62         {
63             if (!this.disposed)
64             {
65                 if (disposing)
66                 {
67                     this.Context.Dispose();
68                 }
69             }
70             this.disposed = true;
71         }
72 
73         public void Dispose()
74         {
75             Dispose(true);
76             GC.SuppressFinalize(this);
77         } 
78     }
79 }
---------------------------
(一).事务
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
1     public class EfStoreDataContext : StoreEntities, IUnitOfWork
2     {
3         public new void SaveChanges()
4         {
5             base.SaveChanges();
6         }
7     }

 

EF生成的访问数据的DbContext

 1 namespace DataAccess
 2 {
 3     using System;
 4     using System.Data.Entity;
 5     using System.Data.Entity.Infrastructure;
 6     using Entities;
 7     
 8     public partial class StoreEntities : DbContext
 9     {
10         public StoreEntities()
11             : base("name=StoreEntities")
12         {
13         }
14     
15         protected override void OnModelCreating(DbModelBuilder modelBuilder)
16         {
17             throw new UnintentionalCodeFirstException();
18         }
19     
20         public DbSet<Contact> Contacts { get; set; }
21         public DbSet<Order> Orders { get; set; }
22     }
23 }

 

IUnitofWork.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Repository
 8 {
 9     public interface IUnitOfWork
10     {
11         void SaveChanges();
12     }
13 }
使用了工作单元 (Unit of work)机制的OrderReposiory:

OrderReposiory.cs:
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using Entities;
 7 using Repository;
 8 
 9 namespace DataAccess.Repositories
10 {
11     public class OrderRepository : BaseRepository, IOrderRepository
12     {
13 
14         public OrderRepository(IUnitOfWork unitOfWork)
15             : base(unitOfWork)
16         {
17 
18         }
19 
20         public IEnumerable<Order> GetAllOrders()
21         {
22             return this.GetDbSet<Order>();
23         }
24 
25         public Order GetByOrderId(int orderId)
26         {
27             return this.GetDbSet<Order>().Find(orderId);
28         }
29 
30         public void Create(Order order)
31         {
32             this.GetDbSet<Order>().Add(order);
33         }
34 
35         public void Update(Order order)
36         {
37             this.SetEntityState(order, System.Data.EntityState.Modified);
38         }
39 
40         public void Delete(int orderId)
41         {
42             var order = this.GetDbSet<Order>().Find(orderId);
43             this.GetDbSet<Order>().Remove(order);
44         }
45     }
46 }

 

根据上面的设计,这行代码:
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





 
 
posted @ 2014-05-05 22:52  easy5  阅读(1733)  评论(2编辑  收藏  举报