<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      導航

      NopCommerce添加事務機制

      NopCommerce,一直沒有事務機制。作為一個商城,我覺得事務也還是很有必要的。以下事務代碼以3.9版本作為參考:

      首先,IDbContext接口繼承IDisposable接口,以便手動釋放相關資源,并添加一個新方法CurrentEntries,目的是得到跟蹤實體的當前跟蹤狀態(tài)(主要作用是使用事務回滾后改變當前實體對應的狀態(tài)):

              /// <summary>
              /// 得到跟蹤實體的當前跟蹤狀態(tài)
              /// </summary>
              /// <returns></returns>
              IEnumerable<DbEntityEntry> CurrentEntries();

      自然相應的IDbContext接口實現(xiàn)類NopObjectContext也要實現(xiàn)該方 CurrentEntries() { return ChangeTracker.Entries(); }

      注意:主項目代碼添加這個方法之后,所有需要操作數(shù)據(jù)庫的插件都要實現(xiàn)該方法,這個大家自行斟酌,如果插件也需要事務的話。

      添加一個接口命名IUnitOfWork,如下:

       

      復制代碼
          public interface IUnitOfWork : IDisposable
          {
              /// <summary>
              /// 開啟事務
              /// </summary>
              /// <param name="isolationLevel"></param>
              void BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.Unspecified);
      
              /// <summary>
              /// 提交
              /// </summary>
              void Commit();
      
              /// <summary>
              /// 回滾
              /// </summary>
              void Rollback();
      
              /// <summary>
              /// 釋放資源
              /// </summary>
              /// <param name="disposing">是否釋放</param>
              void Dispose(bool disposing);
          }
      復制代碼

       

      并實現(xiàn)該接口,添加實現(xiàn)類命名UnitOfWork,如下:

      復制代碼
          public class UnitOfWork : IUnitOfWork
          {
              private IDbContext _context;
              private ObjectContext _objectContext;
              private IDbTransaction _transaction;
      
              private bool _disposed;
      
              public UnitOfWork(IDbContext context)
              {
                  _context = context;
              }
      
              public void BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.Unspecified)
              {
                  _objectContext = ((IObjectContextAdapter)_context).ObjectContext;
                  if (_objectContext.Connection.State != ConnectionState.Open)
                      _objectContext.Connection.Open();
      
                  _transaction = _objectContext.Connection.BeginTransaction(isolationLevel);
              }
      
              public void Commit()
              {
                  _transaction.Commit();
              }
      
              public void Rollback()
              {
                  _transaction.Rollback();
                  foreach (var entry in _context.CurrentEntries())
                  {
                      switch (entry.State)
                      {
                          case EntityState.Modified:
                              entry.State = EntityState.Unchanged;
                              break;
                          case EntityState.Added:
                              entry.State = EntityState.Detached;
                              break;
                          case EntityState.Deleted:
                              entry.State = EntityState.Unchanged;
                              break;
                      }
                  }
              }
      
              public void Dispose(bool disposing)
              {
                  if (_disposed)
                      return;
      
                  if (disposing)
                  {
                      try
                      {
                          if (_objectContext != null && _objectContext.Connection.State == ConnectionState.Open)
                              _objectContext.Connection.Close();
                      }
                      catch (ObjectDisposedException)
                      {
                      }
                      if (_context != null)
                      {
                          _context.Dispose();
                          _context = null;
                      }
                  }
      
                  _disposed = true;
              }
      
              public void Dispose()
              {
                  Dispose(true);
                  GC.SuppressFinalize(this);
              }
          }
      復制代碼

      代碼很好理解,我就不多做注釋了,不清楚的自行網(wǎng)上了解。

      下面附上我寫的單元測試:

      復制代碼
          [TestClass]
          public class UnitTest1
          {
              protected static NopObjectContext Context = new NopObjectContext(ConfigurationManager.ConnectionStrings["ConnectionStr"].ToString());
              private readonly IUnitOfWork _unitOfWork = new UnitOfWork(Context);
              protected readonly IRepository<ForumGroup> ForumGroupRepository = new EfRepository<ForumGroup>(Context);
              protected readonly IRepository<Setting> SettingRepository = new EfRepository<Setting>(Context);
      
              [TestMethod]
              public void Can_Commit_Test()
              {
                  try
                  {
                      _unitOfWork.BeginTransaction(); // 開啟事務
      
                      var forumGroup = new ForumGroup
                      {
                          Name = "ForumGroup1", // 自行建立Name的唯一約束測試,測試兩次第二次會自行回滾
                          DisplayOrder = 1,
                          CreatedOnUtc = DateTime.Now,
                          UpdatedOnUtc = DateTime.Now.AddDays(1)
                      };
                      ForumGroupRepository.Insert(forumGroup); // 第一次插入數(shù)據(jù)
      
                      var setting = new Setting
                      {
                          Name = "test_transaction_name",
                          Value = "test_transaction_value",
                          StoreId = 1
                      };
                      SettingRepository.Insert(setting);
      
                      _unitOfWork.Commit(); // 提交
                  }
                  catch (Exception)
                  {
                      _unitOfWork.Rollback(); // 回滾
                  }
      
                  Assert.AreEqual(ForumGroupRepository.TableNoTracking.Count(), 1);
      Assert.AreEqual(SettingRepository.TableNoTracking.Count(x => x.Name == "test_transaction_name"), 1); } }
      復制代碼
      posted on 2017-12-05 18:04  zrSoldier  閱讀(938)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 久久人人97超碰人人澡爱香蕉| 国产精品国产高清国产一区| 加勒比无码人妻东京热| 人妻丰满熟妇无码区免费| 曰本丰满熟妇xxxx性| 99久久婷婷国产综合精品青草漫画 | 狼色精品人妻在线视频| 日韩欧激情一区二区三区| 亚洲日韩久热中文字幕| 开心色怡人综合网站| 亚洲鸥美日韩精品久久| 久久国产精品精品国产色婷婷| 国产免费网站看v片元遮挡| 免费A级毛片樱桃视频| 国产农村妇女毛片精品久久| 中文字幕无码乱码人妻系列蜜桃| 久久精品一偷一偷国产| 欧美一区二区三区欧美日韩亚洲| 国产精品第一区亚洲精品| 免费大黄网站在线观看| 奇米影视7777狠狠狠狠色| 久久国产乱子精品免费女| 成熟妇女性成熟满足视频| 亚洲精品揄拍自拍首页一| 4hu四虎永久在线观看| 双流县| 久久精品亚洲精品国产区| 开心五月激情五月俺亚洲| 国产成人8X人网站视频| 精品久久久久久国产| 在线 欧美 中文 亚洲 精品| 亚洲岛国成人免费av| 婷婷四房播播| 国内精品久久人妻无码不卡| 一区二区三区人妻无码| 亚洲欧洲日产国码久在线| 久久午夜夜伦鲁鲁片免费无码影院 | 97超级碰碰碰碰久久久久| 狠狠综合久久av一区二| 少妇av一区二区三区无码| 亚洲精品成人福利网站|