参考资料:https://www.cnblogs.com/tuousi99/p/4455573.html
using System;
using System.Data;namespace Manjinba.Dynamics.Domain.Interfaces
{ /// <summary> /// /// </summary> public interface IBaseDbContext : IDisposable { /// <summary> /// /// </summary> IDbConnection Reader { get; } /// <summary> /// /// </summary> IDbConnection Writer { get; } /// <summary> /// /// </summary> void InitConnection(); }}
using Manjinba.Dynamics.Domain.Interfaces;
using Microsoft.Extensions.Configuration;using Microsoft.Extensions.Hosting;using System.Configuration;using System.Data;using System.Data.Common;using Oracle.ManagedDataAccess.Client;namespace Manjinba.Dynamics.Infrastructure.Data.Context
{ /// <summary> /// /// </summary> public class BaseDbContext : DisposableObject, IBaseDbContext { #region Fields private readonly IHostingEnvironment _env; private readonly ConnectionStringSettings _readerConnectString = null; private readonly ConnectionStringSettings _writerConnectString = null; #endregion#region Properties
public IDbConnection Reader { private set; get; } public IDbConnection Writer { private set; get; } #endregion#region Methods
/// <summary> /// /// </summary> /// <param name="env"></param> public BaseDbContext(IHostingEnvironment env) { _env = env; // get the configuration from the app settings var config = new ConfigurationBuilder() .SetBasePath(_env.ContentRootPath) .AddJsonFile("appsettings.json") .Build(); // define the database to use _readerConnectString = new ConnectionStringSettings("DynConnectionString_Reader", config.GetConnectionString("DynConnectionString_Reader"), "Oracle.ManagedDataAccess.Client"); _writerConnectString = new ConnectionStringSettings("DynConnectionString_Writer", config.GetConnectionString("DynConnectionString_Writer"), "Oracle.ManagedDataAccess.Client"); InitConnection(); } /// <summary> /// /// </summary> public void InitConnection() { if (Reader == null) Reader = new OracleConnection(_readerConnectString.ConnectionString); if (Writer == null) Writer = new OracleConnection(_writerConnectString.ConnectionString);//DbProviderFactory dbReaderFactory = DbProviderFactories.GetFactory(this._readerConnectString.ProviderName);
//DbProviderFactory dbWriterFactory = DbProviderFactories.GetFactory(this._writerConnectString.ProviderName);//this.Reader = dbReaderFactory.CreateConnection();
//this.Reader = dbWriterFactory.CreateConnection(); //if (Reader != null) this.Reader.ConnectionString = this._readerConnectString.ConnectionString; //if (Writer != null) this.Writer.ConnectionString = this._writerConnectString.ConnectionString; } /// <summary> /// /// </summary> /// <param name="isDispose"></param> protected override void Dispose(bool isDispose) { if (!isDispose) { return; } if (this.Writer.State == ConnectionState.Open) this.Writer.Close(); if (this.Writer.State == ConnectionState.Open) this.Writer.Dispose(); } #endregion }}
using Manjinba.Dynamics.Domain.Core.Models;
using System;using System.Collections.Generic;using System.Data;namespace Manjinba.Dynamics.Domain.Interfaces
{ /// <summary> /// /// </summary> public interface IUnitOfWork : IDisposable { /// <summary> /// /// </summary> bool Committed { set; get; } /// <summary> /// 数据库执行错误码 /// </summary> IList<int> ErrorCode { get; set; } /// <summary> /// /// </summary> IDbTransaction Tran { get; } /// <summary> /// /// </summary> /// <param name="entity"></param> /// <param name="callback"></param> void RegisterAdd(IEntity entity, Func<int> callback); /// <summary> /// /// </summary> /// <param name="entity"></param> /// <param name="callback"></param> void RegisterUpdate(IEntity entity, Func<int> callback); /// <summary> /// /// </summary> /// <param name="entity"></param> /// <param name="callback"></param> void RegisterDelete(IEntity entity, Func<int> callback); /// <summary> /// /// </summary> void BeginTran(); /// <summary> /// /// </summary> bool Commit(); /// <summary> /// /// </summary> void Rollback(); }}
using Manjinba.Dynamics.Domain.Core.Models;
using Manjinba.Dynamics.Domain.Interfaces;using Manjinba.Dynamics.Infrastructure.Data.Context;using Oracle.ManagedDataAccess.Client;using System;using System.Collections.Generic;using System.Data;using System.Transactions;namespace Manjinba.Dynamics.Infrastructure.Data.UoW
{ /// <summary> /// /// </summary> public class UnitOfWork : IUnitOfWork { #region Fields private readonly IBaseDbContext _dbContext; /// <summary> /// GetRepository方法简单地采用了Dictionary对象来实现缓存仓储实例的效果,当然这种做法还有待改进 /// 懒加载或多线程安全字典 /// </summary> private Dictionary<Type, object> repositoryCache = new Dictionary<Type, object>(); private Dictionary<IEntity, Func<int>> addEntities; private Dictionary<IEntity, Func<int>> updateEntities; private Dictionary<IEntity, Func<int>> deleteEntities; private bool _committed = true; private readonly object _sync = new object(); public IDbTransaction Tran { private set; get; } #endregion#region Properties
public bool Committed { set { _committed = value; } get { return _committed; } }/// <summary>
/// 数据库执行错误码 /// </summary> public IList<int> ErrorCode { get; set; } #endregion#region Methods
/// <summary> /// /// </summary> /// <param name="dbContext"></param> public UnitOfWork(IBaseDbContext dbContext) { _dbContext = dbContext; addEntities = new Dictionary<IEntity, Func<int>>(); updateEntities = new Dictionary<IEntity, Func<int>>(); deleteEntities = new Dictionary<IEntity, Func<int>>(); ErrorCode = new List<int>(); //this.Committed = false; BeginTran(); } /// <summary> /// /// </summary> /// <param name="entity"></param> /// <param name="callback"></param> public void RegisterAdd(IEntity entity, Func<int> callback) { addEntities.Add(entity, callback); } /// <summary> /// /// </summary> /// <param name="entity"></param> /// <param name="callback"></param> public void RegisterUpdate(IEntity entity, Func<int> callback) { updateEntities.Add(entity, callback); } /// <summary> /// /// </summary> /// <param name="entity"></param> /// <param name="callback"></param> public void RegisterDelete(IEntity entity, Func<int> callback) { deleteEntities.Add(entity, callback); } /// <summary> /// /// </summary> public void BeginTran() { _dbContext.Writer.Open(); this.Tran = ((OracleConnection)_dbContext.Writer).BeginTransaction(System.Data.IsolationLevel.ReadCommitted); this.Committed = false; } /// <summary> /// /// </summary> public bool Commit() { var addCnt = 0; var updCnt = 0; var delCnt = 0; foreach (var entity in addEntities.Keys) { var add = addEntities[entity](); if (add > 0) addCnt += add; else ErrorCode.Add(add); } foreach (var entity in updateEntities.Keys) { var upd = updateEntities[entity](); if (upd > 0) updCnt += upd; else ErrorCode.Add(upd); } foreach (var entity in deleteEntities.Keys) { var del = deleteEntities[entity](); if (del > 0) delCnt += del; else ErrorCode.Add(del); } if (addCnt == addEntities.Count && updCnt == updateEntities.Count && delCnt == deleteEntities.Count) { Committed = true; this.Tran.Commit(); return true; } lock (_sync) { this.Tran.Rollback(); this._committed = true; return false; } } /// <summary> /// /// </summary> public void Rollback() { if (Committed) return; lock (_sync) { this.Tran.Rollback(); this._committed = true; } } /// <summary> /// /// </summary> public void Dispose() { this.repositoryCache.Clear(); _dbContext.Dispose(); } #endregion }}