• 【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


    
    


     
     
  • 相关阅读:
    ThreadLocal Thread ThreadLocalMap 之间的关系
    组合注解(Annotation)
    Halo 开源项目使用jsdelivr进行CDN加速.
    如何正确认知和提升自己的“格局”“视野”“高度”?
    格局如何提高?站在未来看今天。
    Cookie 的技术学习笔记
    JVM垃圾收集器与内存分配策略
    java内存区域与内存溢出异常
    JAVA中的BIO,NIO与多路复用(select,poll,epoll)
    Hexo yilia主题搭建自己的github个人博客(一)
  • 原文地址:https://www.cnblogs.com/easy5weikai/p/3710482.html
Copyright © 2020-2023  润新知