【发布时间】:2016-10-22 23:01:30
【问题描述】:
作为学习练习,在尝试使用任何 ORM(如 EF)之前,我想使用 ADO.NET 和存储过程构建一个个人项目。
因为我不希望我的代码随着时间的推移变得一团糟,所以我想使用一些模式,比如存储库和 UoW 模式。
除了事务处理之外,我几乎把所有事情都弄清楚了。
为了以某种方式“模拟”一个 UoW,我使用了 @jgauffin 提供的 this class,但是阻止我使用该类的是,每次创建该类的新实例 (AdoNetUnitOfWork) 时,你都会自动开始一个事务,很多情况下你只需要读取数据。
在这方面,这是我在我一直在阅读的一本 SQL 书籍中发现的:
在事务中执行 SELECT 语句可以在引用的表上创建锁,从而阻止其他用户或会话执行工作或读取数据
这是AdoNetUnitOfWork 类:
public class AdoNetUnitOfWork : IUnitOfWork
{
public AdoNetUnitOfWork(IDbConnection connection, bool ownsConnection)
{
_connection = connection;
_ownsConnection=ownsConnection;
_transaction = connection.BeginTransaction();
}
public IDbCommand CreateCommand()
{
var command = _connection.CreateCommand();
command.Transaction = _transaction;
return command;
}
public void SaveChanges()
{
if (_transaction == null)
throw new InvalidOperationException("Transaction have already been commited. Check your transaction handling.");
_transaction.Commit();
_transaction = null;
}
public void Dispose()
{
if (_transaction != null)
{
_transaction.Rollback();
_transaction = null;
}
if (_connection != null && _ownsConnection)
{
_connection.Close();
_connection = null;
}
}
}
这就是我想在我的存储库中使用 UoW 的方式:
public DomainTable Get(int id)
{
DomainTable table;
using (var commandTable = _unitOfWork.CreateCommand())
{
commandTable.CommandType = CommandType.StoredProcedure;
//This stored procedure contains just a simple SELECT statement
commandTable.CommandText = "up_DomainTable_GetById";
commandTable.Parameters.Add(commandTable.CreateParameter("@pId", id));
table = ToList(commandTable).FirstOrDefault();
}
return table;
}
我知道我可以稍微调整一下这段代码,以便事务是可选的,但是因为我试图让这段代码尽可能独立于平台,而且据我所知,在其他持久性框架(如 EF)中你没有要手动管理事务,问题是,我是否会按原样使用此类,即始终创建事务?
【问题讨论】:
标签: c# sql-server ado.net unit-of-work sqltransaction