咱也搞一个TransactionScope

先来上一段MSDN里的介绍

类提供一个简单方法,通过这一方法,您不必与事务本身交互,即可将代码块标记为参与某个事务。事务范围可以自动选择和管理环境事务。由于它易于使用并且效率很高,因此建议您在开发事务应用程序时使用 TransactionScope 类。

此外,您不必显式向事务登记资源。任何 资源管理器(例如 SQL Server 2005)都可以检测到该范围创建的环境事务的存在并自动登记。


更详细一点的,可以看下面这个网页
http://idior.cnblogs.com/archive/2005/08/15/214300.html


为什么不用自带的""

先简单说说(因为我主要想说他和缺点)的优点:
一:使用起来比较方便.TransactionScope可以实现隐式的事务,使你可以在写数据访问层代码的时候不用

考虑到事务,而在业务层的控制事务.关于这点,可以看Petshop4.0.
二:可以实现分布式事务,比如跨库或MSMQ. 关于这个偶就不用多说了,哈哈.地球人都知道!
好了,说完了好处,来,开始批斗了....蹲地上,唱东方红....


缺点

一:性价比不高.比如,你只是在"Scope"里控制一个库的事务.用"TransactionScope"就有点TMD(请原谅我这

么激动,实现是太不值得了)的浪费了.
二:一般情况下只要你使用"TransactionScope",都要配置MSDTC,要配防火墙,要开139(记不清了,貌似是这个

)端口.问过专业大牛,人家说了,这个端口不可以更改,日(对不起,我太生气了..)

基于上面这二个问题,偶们决定"Scope"再好,偶们也不用了(拼了),但是,偶们还想实现那种类似于隐式的

事务代码(这个太勾引人了).于是,偶们搞出了这个自己的"Scope"(注意,偶这个只能实现数据库的事务而且不是分布式的,当然不用开端口,也基本无性能问题).

实现原理
 偶是不指望实现自己的事务管理器来实现自己"Scope"了,于是偶想到了这个办法分三步实现.
一.在实例化自己的"Scope"时,记一个事务标志位.
二.在访问数据库时,查看有没有事务标志位.如果有,从"Scope"取一个数据库事务.将这个事务赋给DBCommand,并将这个事务和连接记下来,如果下次有同样的连接字符串请示事务,就将这个事务发给他.
三.在我们的"Scope"被Dispose时,判断用户调没调用Complete方法,如果调了,说明用户提交了事务,没调就说明事务回滚(和"TransactionScope"是一样的).然后提交或回滚所有的DBTransaction.

根据上面的实现,偶们需要控制用户数据访问方式,也就是说让他们用偶们提供的数据访问代码,才能实现我们自己的"Scope".于是,偶想到了企业库.偶用的是企业库3.1版的

下面开始放代码
先放实现后的调用代码,是不是和"TransactionScope"很像?
DJTransactionScope (偶这个项目是DJ开头的,DJ呵呵)

using (DJTransactionscope scope = new  (DJTransactionscope ())

{

//要确保对支持事务的资源的登记放在此范围内,如数据库资源的打开

A a
=new A();

a.method();

..
B b 
= new b();
b.method();

scope.comlete()

}
 



using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Collections;
using  System.Data.Common;
using  Microsoft.Practices.EnterpriseLibrary.Data;
using  System.Web;
using  System.Threading;

namespace  DJ.Framework.Transaction
{
    
public class DJTransactionScope : IDisposable
    
{
        
/**//// <summary>
        
/// 标志位,标志用户是不是提交了事务
        
/// </summary>

        private bool isCompleted = false;
        
/**//// <summary>
        
/// 存放已加入的事务的Connection的
        
/// </summary>

        private Dictionary<String, ConnAndTranPaire> transactionPool = new Dictionary<string, ConnAndTranPaire>();

        
/**//// <summary>
        
/// 用来存放WinFrom程序中的事务
        
/// </summary>

        [ThreadStatic]
        
private static DJTransactionScope currentScope;

        
/**//// <summary>
        
/// 取得当前事务
        
/// </summary>

        public static DJTransactionScope Current
        
{
            
get
            
{
                
//如果这不是一个Web项目
                if (HttpContext.Current == null)
                
{
                    
return currentScope;
                }

                
else
                
{
                    
//Web项目的话,就把事务标志放到HttpContext中
                    HttpContext context = HttpContext.Current;
                    
                    
return context.Items["CurrentTransactionScope"as DJTransactionScope;
                }

            }

            
private set
            
{
                
                
if (HttpContext.Current == null)
                
{
                    currentScope 
= value;
                }

                
else
                
{
                    HttpContext context 
= HttpContext.Current;
                  

                    
if (context.Items.Contains("CurrentTransactionScope"))
                        context.Items[
"CurrentTransactionScope"= value;
                    
else
                        context.Items.Add(
"CurrentTransactionScope", value);
                   
                }

            }

        }


        
private Guid scopeID = Guid.NewGuid();
        
/**//// <summary>
        
/// 事务ID
        
/// </summary>

        public Guid ScopeID
        
{
            
get
            
{
                
return scopeID;
            }

        }


        
/**//// <summary>
        
/// 构造方法
        
/// </summary>

        public DJTransactionScope()
        
{
            
//如果当前没有起动事务,就记下此标志
            if (Current == null)
            
{
                Current 
= this;
            }

        }


        
/**//// <summary>
        
/// 调用此方法,将会在代码段结束后提交事务
        
/// </summary>

        public void Complete()
        
{
            
//记录用户的提示
            isCompleted = true;
        }


        
/**//// <summary>
        
/// 加入当前事务
        
/// </summary>
        
/// <param name="database"></param>
        
/// <returns></returns>

        public DbTransaction JoinTransaction(Database database)
        
{
            
            
if (transactionPool.ContainsKey(database.ConnectionStringWithoutCredentials))
            
{
                
return transactionPool[database.ConnectionStringWithoutCredentials].Transaction;
            }

            
else
            
{

                DbConnection dbconnection 
= database.CreateConnection();
                dbconnection.Open();
                DbTransaction dbTransaction 
= dbconnection.BeginTransaction();

                ConnAndTranPaire paire 
= new ConnAndTranPaire();

                paire.Connection 
= dbconnection;
                paire.Transaction 
= dbTransaction;

                transactionPool.Add(database.ConnectionStringWithoutCredentials, paire);
                
return paire.Transaction;

            }

        }


        
public override bool Equals(object obj)
        
{
            
if (obj is DJTransactionScope)
            
{
                DJTransactionScope scope 
= obj as DJTransactionScope;

                
return (scope.scopeID == this.scopeID);
            }


            
return false;

        }


        
public override int GetHashCode()
        
{
            
return scopeID.GetHashCode();
        }


        
IDisposable 成员#region IDisposable 成员
        
/**//// <summary>
        
/// 销毁资源
        
/// </summary>

        public void Dispose()
        
{

            
if (Current == null)
                
return;

            
if (Current.scopeID != this.scopeID)
                
return;

            
foreach (String connString in transactionPool.Keys)
            
{
                
try
                
{
                    
//如果用户提交了事务
                    if (isCompleted)
                        transactionPool[connString].Transaction.Commit();
                    
else
                        transactionPool[connString].Transaction.Rollback();
                }

                
finally
                
{
                    
//关闭所有的连接
                    DbConnection conn = transactionPool[connString].Connection;

                    
if (conn != null && conn.State != System.Data.ConnectionState.Closed)
                        transactionPool[connString].Connection.Close();

                    transactionPool[connString].Transaction.Dispose();
                        
                }

            }

            
//去掉事务标志
            RemoveTransaction();

        }


        
#endregion


        
private void RemoveTransaction()
        
{
            Current 
= null;
        }

    }


    
/**//// <summary>
    
/// 放事务和连接类
    
/// </summary>

    class ConnAndTranPaire
    
{
        
public DbConnection Connection;
        
public DbTransaction Transaction;
    }

}


偶建议把上面这个类放到一个单独的DLL里

下的代码包装了企业的数据访问部分

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Data;
using  System.Data.Common;
using  System.Reflection;
using  Microsoft.Practices.EnterpriseLibrary.Data;
using  Microsoft.Practices.EnterpriseLibrary.Data.Sql;
using  Microsoft.Practices.EnterpriseLibrary.Data.Oracle;
using  DJ.Framework.DataObjects;
using  DJ.Framework.Transaction;

namespace  DJ.Framework.DataAccess
{
    
public class ExDatabase
    
{
        
protected Database innerDatabase;

        
protected ExDatabase(Database database)
        
{
            innerDatabase 
= database;
        }


        
/**//// <summary>
        
/// 获取ExDatabase实例
        
/// </summary>
        
/// <returns>ExDatabase实例</returns>

        public static ExDatabase CreateDatabase()
        
{
            
return new ExDatabase(DatabaseFactory.CreateDatabase());
        }


        
/**//// <summary>
        
/// 获取ExDatabase实例
        
/// </summary>
        
/// <param name="name">连接标识</param>
        
/// <returns>ExDatabase实例</returns>

        public static ExDatabase CreateDatabase(String name)
        
{
            
return new ExDatabase(DatabaseFactory.CreateDatabase(name));
        }


       

        
Execute Something#region Execute Something
        
/**//// <summary>
        
/// 执行查询语句,从数据库中返回结果集
        
/// </summary>
        
/// <param name="sqlSentence">查询字符串</param>
        
/// <returns>数据集</returns>

        public DataSet ExecuteDataSet(String sqlSentence)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteDataSet(transaction, CommandType.Text, sqlSentence);
            }


            
return innerDatabase.ExecuteDataSet(CommandType.Text, sqlSentence);
        }


        
/**//// <summary>
        
/// 执行存储过程,从数据库中返回结果集
        
/// </summary>
        
/// <param name="storedProcedureName">存储过程名</param>
        
/// <param name="parameterValues">存储过程参数对象数组</param>
        
/// <returns>数据集</returns>

        public DataSet ExecuteDataSet(String storedProcedureName, params Object[] parameterValues)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteDataSet(transaction, storedProcedureName, parameterValues);
            }


            
return innerDatabase.ExecuteDataSet(storedProcedureName, parameterValues);
        }


        
/**//// <summary>
        
/// <para>Executes the <paramref name="commandText"/> interpreted as specified by the <paramref name="commandType" /> and returns the results in a new <see cref="DataSet"/>.</para>
        
/// </summary>
        
/// <param name="commandType">
        
/// <para>One of the <see cref="CommandType"/> values.</para>
        
/// </param>
        
/// <param name="commandText">
        
/// <para>The command text to execute.</para>
        
/// </param>
        
/// <returns>
        
/// <para><see cref="DataSet"/> with the results of the <paramref name="commandText"/>.</para>
        
/// </returns>   

        public DataSet ExecuteDataSet(CommandType commandType, string commandText)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteDataSet(transaction, commandType, commandText);
            }


            
return innerDatabase.ExecuteDataSet(commandType, commandText);
        }


        
/**//// <summary>
        
/// <para>Executes the <paramref name="command"/> and returns the results in a new <see cref="DataSet"/>.</para>
        
/// </summary>
        
/// <param name="command"><para>The <see cref="DbCommand"/> to execute.</para></param>
        
/// <returns><see cref="DataSet"/> with the results of the <paramref name="command"/>.</returns> 

        public DataSet ExecuteDataSet(DbCommand command)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteDataSet(command, transaction);
            }


            
return innerDatabase.ExecuteDataSet(command);
        }


        
/**//// <summary>
        
/// 执行语句,返回受影响行数
        
/// </summary>
        
/// <param name="sqlSentence">查询字符串</param>
        
/// <returns>受影响的行数</returns>

        public Int32 ExecuteNonQuery(String sqlSentence)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteNonQuery(transaction, CommandType.Text, sqlSentence);
            }


            
return innerDatabase.ExecuteNonQuery(CommandType.Text, sqlSentence);
        }


        
/**//// <summary>
        
/// 执行存储过程,返回受影响行数
        
/// </summary>
        
/// <param name="storedProcedureName">存储过程名</param>
        
/// <param name="parameterValues">存储过程参数对象数组</param>
        
/// <returns>受影响的行数</returns>

        public Int32 ExecuteNonQuery(String storedProcedureName, params Object[] parameterValues)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteNonQuery(transaction, storedProcedureName, parameterValues);
            }


            
return innerDatabase.ExecuteNonQuery(storedProcedureName, parameterValues);
        }


        
/**//// <summary>
        
/// <para>Executes the <paramref name="commandText"/> interpreted as specified by the <paramref name="commandType" /> and returns the number of rows affected.</para>
        
/// </summary>
        
/// <param name="commandType">
        
/// <para>One of the <see cref="CommandType"/> values.</para>
        
/// </param>
        
/// <param name="commandText">
        
/// <para>The command text to execute.</para>
        
/// </param>
        
/// <returns>
        
/// <para>The number of rows affected.</para>
        
/// </returns>
        
/// <seealso cref="IDbCommand.ExecuteScalar"/>

        public int ExecuteNonQuery(CommandType commandType, string commandText)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteNonQuery(transaction, commandType, commandText);
            }


            
return innerDatabase.ExecuteNonQuery(commandType, commandText);
        }


        
/**//// <summary>
        
/// <para>Executes the <paramref name="command"/> and returns the number of rows affected.</para>
        
/// </summary>
        
/// <param name="command">
        
/// <para>The command that contains the query to execute.</para>
        
/// </param>       
        
/// <seealso cref="IDbCommand.ExecuteScalar"/>

        public virtual int ExecuteNonQuery(DbCommand command)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteNonQuery(command, transaction);
            }


            
return innerDatabase.ExecuteNonQuery(command);

        }


        
/**//// <summary>
        
/// 执行查询语句,从数据库中返回IDataReader
        
/// </summary>
        
/// <param name="sqlSentence">查询字符串</param>
        
/// <returns>IDataReader</returns>

        public IDataReader ExecuteReader(String sqlSentence)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteReader(transaction, CommandType.Text, sqlSentence);
            }


            
return innerDatabase.ExecuteReader(CommandType.Text, sqlSentence);
        }


        
/**//// <summary>
        
/// 执行存储过程,从数据库中返回IDataReader
        
/// </summary>
        
/// <param name="storedProcedureName">存储过程名</param>
        
/// <param name="parameterValues">存储过程参数对象数组</param>
        
/// <returns>IDataReader</returns>

        public IDataReader ExecuteReader(String storedProcedureName, params Object[] parameterValues)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteReader(transaction, storedProcedureName, parameterValues);
            }


            
return innerDatabase.ExecuteReader(storedProcedureName, parameterValues);
        }


        
/**//// <summary>
        
/// <para>Executes the <paramref name="commandText"/> interpreted as specified by the <paramref name="commandType" /> and returns an <see cref="IDataReader"></see> through which the result can be read.
        
/// It is the responsibility of the caller to close the connection and reader when finished.</para>
        
/// </summary>
        
/// <param name="commandType">
        
/// <para>One of the <see cref="CommandType"/> values.</para>
        
/// </param>
        
/// <param name="commandText">
        
/// <para>The command text to execute.</para>
        
/// </param>
        
/// <returns>
        
/// <para>An <see cref="IDataReader"/> object.</para>
        
/// </returns>        

        public IDataReader ExecuteReader(CommandType commandType, string commandText)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteReader(transaction, commandType, commandText);
            }


            
return innerDatabase.ExecuteReader(commandType, commandText);
        }


        
/**//// <summary>
        
/// <para>Executes the <paramref name="command"/> and returns an <see cref="IDataReader"></see> through which the result can be read.
        
/// It is the responsibility of the caller to close the connection and reader when finished.</para>
        
/// </summary>
        
/// <param name="command">
        
/// <para>The command that contains the query to execute.</para>
        
/// </param>
        
/// <returns>
        
/// <para>An <see cref="IDataReader"/> object.</para>
        
/// </returns>        

        public virtual IDataReader ExecuteReader(DbCommand command)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteReader(command, transaction);
            }


            
return innerDatabase.ExecuteReader(command);
        }


        
/**//// <summary>
        
/// 执行查询语句,从数据库中返回结果对象
        
/// </summary>
        
/// <param name="sqlSentence">查询字符串</param>
        
/// <returns>结果对象</returns>

        public Object ExecuteScalar(String sqlSentence)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteScalar(transaction, CommandType.Text, sqlSentence);
            }


            
return innerDatabase.ExecuteScalar(CommandType.Text, sqlSentence);
        }


        
/**//// <summary>
        
/// 执行存储过程,从数据库中返回结果对象
        
/// </summary>
        
/// <param name="storedProcedureName">存储过程名</param>
        
/// <param name="parameterValues">存储过程参数对象数组</param>
        
/// <returns>结果对象</returns>

        public Object ExecuteScalar(String storedProcedureName, params Object[] parameterValues)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteScalar(transaction, storedProcedureName, parameterValues);
            }


            
return innerDatabase.ExecuteScalar(storedProcedureName, parameterValues);
        }


        
/**//// <summary>
        
/// <para>Executes the <paramref name="commandText"/> interpreted as specified by the <paramref name="commandType" />  and returns the first column of the first row in the result set returned by the query. Extra columns or rows are ignored.</para>
        
/// </summary>
        
/// <param name="commandType">
        
/// <para>One of the <see cref="CommandType"/> values.</para>
        
/// </param>
        
/// <param name="commandText">
        
/// <para>The command text to execute.</para>
        
/// </param>
        
/// <returns>
        
/// <para>The first column of the first row in the result set.</para>
        
/// </returns>
        
/// <seealso cref="IDbCommand.ExecuteScalar"/>

        public virtual object ExecuteScalar(CommandType commandType, string commandText)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteScalar(transaction, commandType, commandText);
            }


            
return innerDatabase.ExecuteScalar(commandType, commandText);
        }


        
/**//// <summary>
        
/// <para>Executes the <paramref name="command"/> and returns the first column of the first row in the result set returned by the query. Extra columns or rows are ignored.</para>
        
/// </summary>
        
/// <param name="command">
        
/// <para>The command that contains the query to execute.</para>
        
/// </param>
        
/// <returns>
        
/// <para>The first column of the first row in the result set.</para>
        
/// </returns>
        
/// <seealso cref="IDbCommand.ExecuteScalar"/>

        public virtual object ExecuteScalar(DbCommand command)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.ExecuteScalar(command, transaction);
            }


            
return innerDatabase.ExecuteScalar(command);
        }


        
#endregion


        
Update DataSet#region Update DataSet
        
/**//// <summary>
        
/// 更新数据集
        
/// </summary>
        
/// <param name="dataSet">数据集</param>
        
/// <param name="tableName">表名</param>
        
/// <param name="insertCommand">插入命令</param>
        
/// <param name="updateCommand">更新命令</param>
        
/// <param name="deleteCommand">删除命令</param>
        
/// <returns>受影响的行数</returns>

        public Int32 UpdateDataSet(DataSet dataSet, String tableName
            , DbCommand insertCommand, DbCommand updateCommand, DbCommand deleteCommand)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.UpdateDataSet(dataSet, tableName, insertCommand, updateCommand, deleteCommand, transaction);
            }


            
return innerDatabase.UpdateDataSet(dataSet, tableName, insertCommand, updateCommand, deleteCommand, UpdateBehavior.Standard);
        }


        
/**//// <summary>
        
/// 更新数据集
        
/// </summary>
        
/// <param name="dataSet">数据集</param>
        
/// <param name="tableName">表名</param>
        
/// <param name="insertCommand">插入命令</param>
        
/// <param name="updateCommand">更新命令</param>
        
/// <param name="deleteCommand">删除命令</param>
        
/// <param name="updateBatchSize">The number of commands that can be executed in a single call to the database. Set to 0 to
        
/// use the largest size the server can handle, 1 to disable batch updates, and anything else to set the number of rows.
        
/// </param>
        
/// <returns>受影响的行数</returns>

        public Int32 UpdateDataSet(DataSet dataSet, string tableName
            , DbCommand insertCommand, DbCommand updateCommand, DbCommand deleteCommand, 
int? updateBatchSize)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                
return innerDatabase.UpdateDataSet(dataSet, tableName, insertCommand, updateCommand, deleteCommand, transaction, updateBatchSize);
            }


            
return innerDatabase.UpdateDataSet(dataSet, tableName, insertCommand, updateCommand, deleteCommand, UpdateBehavior.Standard, updateBatchSize);
        }

        
#endregion


        
Load DataSet#region Load DataSet
        
/**//// <summary>
        
/// <para>Loads a <see cref="DataSet"/> from command text.</para>
        
/// </summary>
        
/// <param name="commandType">
        
/// <para>One of the <see cref="CommandType"/> values.</para>
        
/// </param>
        
/// <param name="commandText">
        
/// <para>The command text to execute.</para>
        
/// </param>
        
/// <param name="dataSet">
        
/// <para>The <see cref="DataSet"/> to fill.</para>
        
/// </param>
        
/// <param name="tableNames">
        
/// <para>An array of table name mappings for the <see cref="DataSet"/>.</para>
        
/// </param>

        public void LoadDataSet(CommandType commandType, string commandText, DataSet dataSet, string[] tableNames)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                innerDatabase.LoadDataSet(transaction, commandType, commandText, dataSet, tableNames);
            }

            
else
                innerDatabase.LoadDataSet(commandType, commandText, dataSet, tableNames);
        }


        
/**//// <summary>
        
/// <para>Executes the <paramref name="command"/> and adds a new <see cref="DataTable"></see> to the existing <see cref="DataSet"></see>.</para>
        
/// </summary>
        
/// <param name="command">
        
/// <para>The <see cref="DbCommand"/> to execute.</para>
        
/// </param>
        
/// <param name="dataSet">
        
/// <para>The <see cref="DataSet"/> to load.</para>
        
/// </param>
        
/// <param name="tableName">
        
/// <para>The name for the new <see cref="DataTable"/> to add to the <see cref="DataSet"/>.</para>
        
/// </param>        
        
/// <exception cref="System.ArgumentNullException">Any input parameter was <see langword="null"/> (<b>Nothing</b> in Visual Basic)</exception>
        
/// <exception cref="System.ArgumentException">tableName was an empty string</exception>

        public void LoadDataSet(DbCommand command, DataSet dataSet, string tableName)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                innerDatabase.LoadDataSet(command, dataSet, tableName, transaction);
            }

            
else
                innerDatabase.LoadDataSet(command, dataSet, tableName);
        }


        
/**//// <summary>
        
/// <para>Loads a <see cref="DataSet"/> from a <see cref="DbCommand"/>.</para>
        
/// </summary>
        
/// <param name="command">
        
/// <para>The command to execute to fill the <see cref="DataSet"/>.</para>
        
/// </param>
        
/// <param name="dataSet">
        
/// <para>The <see cref="DataSet"/> to fill.</para>
        
/// </param>
        
/// <param name="tableNames">
        
/// <para>An array of table name mappings for the <see cref="DataSet"/>.</para>
        
/// </param>

        public void LoadDataSet(DbCommand command, DataSet dataSet, string[] tableNames)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                innerDatabase.LoadDataSet(command, dataSet, tableNames, transaction);
            }

            
else
                innerDatabase.LoadDataSet(command, dataSet, tableNames);
        }


        
/**//// <summary>
        
/// <para>Loads a <see cref="DataSet"/> with the results returned from a stored procedure.</para>
        
/// </summary>
        
/// <param name="storedProcedureName">
        
/// <para>The stored procedure name to execute.</para>
        
/// </param>
        
/// <param name="dataSet">
        
/// <para>The <see cref="DataSet"/> to fill.</para>
        
/// </param>
        
/// <param name="tableNames">
        
/// <para>An array of table name mappings for the <see cref="DataSet"/>.</para>
        
/// </param>
        
/// <param name="parameterValues">
        
/// <para>An array of paramters to pass to the stored procedure. The parameter values must be in call order as they appear in the stored procedure.</para>
        
/// </param>

        public void LoadDataSet(string storedProcedureName, DataSet dataSet, string[] tableNames, params object[] parameterValues)
        
{
            
if (DJTransactionScope.Current != null)
            
{
                DbTransaction transaction 
= DJTransactionScope.Current.JoinTransaction(innerDatabase);

                innerDatabase.LoadDataSet(transaction, storedProcedureName, dataSet, tableNames, parameterValues);
            }

            
else
                innerDatabase.LoadDataSet(storedProcedureName, dataSet, tableNames, parameterValues);
        }

        
#endregion


        
Parameter Function#region Parameter Function
        
/**//// <summary>
        
/// Adds a new In <see cref="DbParameter"/> object to the given <paramref name="command"/>.
        
/// </summary>
        
/// <param name="command">The command to add the in parameter.</param>
        
/// <param name="name"><para>The name of the parameter.</para></param>
        
/// <param name="dbType"><para>One of the <see cref="DbType"/> values.</para></param>                
        
/// <remarks>
        
/// <para>This version of the method is used when you can have the same parameter object multiple times with different values.</para>
        
/// </remarks>

        public void AddInParameter(DbCommand command, string name, DbType dbType)
        
{
            innerDatabase.AddInParameter(command, name, dbType);
        }


        
/**//// <summary>
        
/// Adds a new In <see cref="DbParameter"/> object to the given <paramref name="command"/>.
        
/// </summary>
        
/// <param name="command">The commmand to add the parameter.</param>
        
/// <param name="name"><para>The name of the parameter.</para></param>
        
/// <param name="dbType"><para>One of the <see cref="DbType"/> values.</para></param>
        
/// <param name="value"><para>The value of the parameter.</para></param>

        public void AddInParameter(DbCommand command, string name, DbType dbType, object value)
        
{
            innerDatabase.AddInParameter(command, name, dbType, value);
        }


        
/**//// <summary>
        
/// Adds a new In <see cref="DbParameter"/> object to the given <paramref name="command"/>.
        
/// </summary>
        
/// <param name="command">The command to add the parameter.</param>
        
/// <param name="name"><para>The name of the parameter.</para></param>
        
/// <param name="dbType"><para>One of the <see cref="DbType"/> values.</para></param>
        
/// <param name="sourceColumn"><para>The name of the source column mapped to the DataSet and used for loading or returning the value.</para></param>
        
/// <param name="sourceVersion"><para>One of the <see cref="DataRowVersion"/> values.</para></param>

        public void AddInParameter(DbCommand command, string name, DbType dbType, string sourceColumn, DataRowVersion sourceVersion)
        
{
            innerDatabase.AddInParameter(command, name, dbType, sourceColumn, sourceVersion);
        }


        
/**//// <summary>
        
/// Adds a new Out <see cref="DbParameter"/> object to the given <paramref name="command"/>.
        
/// </summary>
        
/// <param name="command">The command to add the out parameter.</param>
        
/// <param name="name"><para>The name of the parameter.</para></param>
        
/// <param name="dbType"><para>One of the <see cref="DbType"/> values.</para></param>
        
/// <param name="size"><para>The maximum size of the data within the column.</para></param>

        public void AddOutParameter(DbCommand command, string name, DbType dbType, int size)
        
{
            innerDatabase.AddInParameter(command, name, dbType, size);
        }


        
/**//// <summary>
        
/// Adds a new In <see cref="DbParameter"/> object to the given <paramref name="command"/>.
        
/// </summary>
        
/// <param name="command">The command to add the parameter.</param>
        
/// <param name="name"><para>The name of the parameter.</para></param>
        
/// <param name="dbType"><para>One of the <see cref="DbType"/> values.</para></param>
        
/// <param name="size"><para>The maximum size of the data within the column.</para></param>
        
/// <param name="direction"><para>One of the <see cref="ParameterDirection"/> values.</para></param>
        
/// <param name="nullable"><para>Avalue indicating whether the parameter accepts <see langword="null"/> (<b>Nothing</b> in Visual Basic) values.</para></param>
        
/// <param name="precision"><para>The maximum number of digits used to represent the <paramref name="value"/>.</para></param>
        
/// <param name="scale"><para>The number of decimal places to which <paramref name="value"/> is resolved.</para></param>
        
/// <param name="sourceColumn"><para>The name of the source column mapped to the DataSet and used for loading or returning the <paramref name="value"/>.</para></param>
        
/// <param name="sourceVersion"><para>One of the <see cref="DataRowVersion"/> values.</para></param>
        
/// <param name="value"><para>The value of the parameter.</para></param>   

        public void AddParameter(DbCommand command, string name, DbType dbType, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)
        
{
            innerDatabase.AddParameter(command, name, dbType, size, direction, nullable, precision, scale, sourceColumn, sourceVersion, value);
        }


        
/**//// <summary>
        
/// <para>Adds a new instance of a <see cref="DbParameter"/> object to the command.</para>
        
/// </summary>
        
/// <param name="command">The command to add the parameter.</param>
        
/// <param name="name"><para>The name of the parameter.</para></param>
        
/// <param name="dbType"><para>One of the <see cref="DbType"/> values.</para></param>
        
/// <param name="direction"><para>One of the <see cref="ParameterDirection"/> values.</para></param>
        
/// <param name="sourceColumn"><para>The name of the source column mapped to the DataSet and used for loading or returning the <paramref name="value"/>.</para></param>
        
/// <param name="sourceVersion"><para>One of the <see cref="DataRowVersion"/> values.</para></param>
        
/// <param name="value"><para>The value of the parameter.</para></param>

        public void AddParameter(DbCommand command, string name, DbType dbType, ParameterDirection direction, string sourceColumn, DataRowVersion sourceVersion, object value)
        
{
            innerDatabase.AddParameter(command, name, dbType, direction, sourceColumn, sourceVersion, value);
        }

        
/**//// <summary>
        
/// 构造参数名(插入@/:)
        
/// </summary>
        
/// <param name="name">原始参数名</param>
        
/// <returns>(@/:)+参数名</returns>

        public String BuildParameterName(String name)
        
{
            Type dbType 
= innerDatabase.GetType();

            
if (dbType == typeof(SqlDatabase))
                
return innerDatabase.BuildParameterName(name);
            
else if (dbType == typeof(OracleDatabase))
            
{
                
if (name != null && name.Length > 0 && name[0!= ':')
                    
return name.Insert(0":");
            }


            
return name;
        }


        
/**//// <summary>
        
/// 清除存储过程的参数缓存(如果存储过程的参数有变化则需要调用此方法)
        
/// </summary>

        public static void ClearParameterCache()
        
{
            Database.ClearParameterCache();
        }


        
/**//// <summary>
        
/// Discovers the parameters for a <see cref="DbCommand"/>.
        
/// </summary>
        
/// <param name="command">The <see cref="DbCommand"/> to discover the parameters.</param>

        public void DiscoverParameters(DbCommand command)
        
{
            innerDatabase.DiscoverParameters(command);
        }


        
/**//// <summary>
        
/// Sets a parameter value.
        
/// </summary>
        
/// <param name="command">The command with the parameter.</param>
        
/// <param name="parameterName">The parameter name.</param>
        
/// <param name="value">The parameter value.</param>

        public void SetParameterValue(DbCommand command, string parameterName, object value)
        
{
            innerDatabase.SetParameterValue(command, parameterName, value);
        }

        
#endregion


        
Get Something#region Get Something
        
/**//// <summary>
        
/// Gets a DbDataAdapter with Standard update behavior.
        
/// </summary>
        
/// <returns><see cref="DbDataAdapter"/>.</returns>
        
/// <seealso cref="DbDataAdapter"/>
        
/// <devdoc>
        
/// Created this new, public method instead of modifying the protected, abstract one so that there will be no
        
/// breaking changes for any currently derived Database class.
        
/// </devdoc>

        public DbDataAdapter GetDataAdapter()
        
{
            
return innerDatabase.GetDataAdapter();
        }


        
/**//// <summary>
        
/// Gets a parameter value.
        
/// </summary>
        
/// <param name="command">The command that contains the parameter.</param>
        
/// <param name="name">The name of the parameter.</param>
        
/// <returns>The value of the parameter.</returns>

        public object GetParameterValue(DbCommand command, string name)
        
{
            
return innerDatabase.GetParameterValue(command, name);
        }


        
/**//// <summary>
        
/// <para>Creates a <see cref="DbCommand"/> for a SQL query.</para>
        
/// </summary>
        
/// <param name="query"><para>The text of the query.</para></param>        
        
/// <returns><para>The <see cref="DbCommand"/> for the SQL query.</para></returns>        

        public DbCommand GetSqlStringCommand(string query)
        
{
            
return innerDatabase.GetSqlStringCommand(query);
        }


        
/**//// <summary>
        
/// <para>Creates a <see cref="DbCommand"/> for a stored procedure.</para>
        
/// </summary>
        
/// <param name="storedProcedureName"><para>The name of the stored procedure.</para></param>
        
/// <returns><para>The <see cref="DbCommand"/> for the stored procedure.</para></returns>       

        public DbCommand GetStoredProcCommand(string storedProcedureName)
        
{
            
return innerDatabase.GetStoredProcCommand(storedProcedureName);
        }


        
/**//// <summary>
        
/// <para>Creates a <see cref="DbCommand"/> for a stored procedure.</para>
        
/// </summary>
        
/// <param name="storedProcedureName"><para>The name of the stored procedure.</para></param>
        
/// <param name="parameterValues"><para>The list of parameters for the procedure.</para></param>
        
/// <returns><para>The <see cref="DbCommand"/> for the stored procedure.</para></returns>
        
/// <remarks>
        
/// <para>The parameters for the stored procedure will be discovered and the values are assigned in positional order.</para>
        
/// </remarks>        

        public DbCommand GetStoredProcCommand(string storedProcedureName, params object[] parameterValues)
        
{
            
return innerDatabase.GetStoredProcCommand(storedProcedureName, parameterValues);
        }


        
/**//// <summary>
        
/// Wraps around a derived class's implementation of the GetStoredProcCommandWrapper method and adds functionality for
        
/// using this method with UpdateDataSet.  The GetStoredProcCommandWrapper method (above) that takes a params array 
        
/// expects the array to be filled with VALUES for the parameters. This method differs from the GetStoredProcCommandWrapper 
        
/// method in that it allows a user to pass in a string array. It will also dynamically discover the parameters for the 
        
/// stored procedure and set the parameter's SourceColumns to the strings that are passed in. It does this by mapping 
        
/// the parameters to the strings IN ORDER. Thus, order is very important.
        
/// </summary>
        
/// <param name="storedProcedureName"><para>The name of the stored procedure.</para></param>
        
/// <param name="sourceColumns"><para>The list of DataFields for the procedure.</para></param>
        
/// <returns><para>The <see cref="DbCommand"/> for the stored procedure.</para></returns>

        public DbCommand GetStoredProcCommandWithSourceColumns(string storedProcedureName, params string[] sourceColumns)
        
{
            
return innerDatabase.GetStoredProcCommandWithSourceColumns(storedProcedureName, sourceColumns);
        }

        
#endregion

    }

}

 

好的,到这里,我们自己的"Scope"就实现了.
优点就是不用起分布式事务,隐式的实现事务(至少看起来是)
缺点,就是不支持真正的分布式事务.只能起数据库事务,必须用我们封装的数据访问代码


先放到这,有没写的明白的地方,请大家留言给我,我会补充上来



转载于:https://www.cnblogs.com/listhome/archive/2007/12/01/979603.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值