参考资料: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
}
}