//by lostinet.com
using System;
using System.Collections;
using System.Data.SqlClient;namespace ct
{
public class SqlScopeException:Exception
{
public SqlScopeException(string message)
:base(message)
{
}
public SqlScopeException(string message,Exception innerException)
:base(message,innerException)
{
}
}
/// <summary>
/// 通过传递SqlScope,实现SqlConnection,SqlTransaction的创建,起用,传递和释放
/// </summary>
public class SqlScope:IDisposable
{
string connString;
SqlConnection conn=null;
SqlTransaction trans=null;
Stack stack=null; public SqlConnection Connection
{
get
{
CheckConnection();
return conn;
}
}
public SqlTransaction Transaction
{
get
{
CheckConnection();
return trans;
}
}
public string ConnectionString
{
get
{
return connString;
}
}
static public implicit operator SqlConnection (SqlScope ss)
{
return ss.Connection;
}
static public implicit operator SqlTransaction (SqlScope ss)
{
return ss.Transaction;
} public SqlScope(string ConnectionString)
{
if(ConnectionString==null)
throw(new ArgumentNullException("ConnectionString"));
connString=ConnectionString;
}
~SqlScope()
{
Dispose();
}
public void Dispose()
{
stack=null;
try
{
if(trans!=null)
trans.Dispose();
}
finally
{
try
{
if(conn!=null)
conn.Dispose();
}
finally
{
conn=null;
trans=null;
}
}
}
void OpenConnection(bool beginTransaction)
{
if(stack!=null)
throw(new SqlScopeException("Connection已经被打开!"));
stack=new Stack();
conn=new SqlConnection(connString);
conn.Open();
if(beginTransaction)
trans=conn.BeginTransaction("trans");
}
void CheckConnection()
{
if(stack==null)
throw(new SqlScopeException("Connection没有打开或者已经被关闭"));
}
public SqlCommand CreateCommand(string commandText)
{
if(commandText==null)
throw(new ArgumentNullException("commandText"));
CheckConnection();
return new SqlCommand(commandText,conn,trans);
}
public SqlDataAdapter CreateAdapter(string commandText)
{
if(commandText==null)
throw(new ArgumentNullException("commandText"));
CheckConnection();
return new SqlDataAdapter(CreateCommand(commandText));
}
/// <summary>
/// 和Commit或Rollback对应
/// </summary>
public void BeginTransaction()
{
if(stack==null)
{
try
{
OpenConnection(true);
}
catch(Exception x)
{
Dispose();
throw(x);
}
}
else
{
trans.Save("trans"+stack.Count.ToString());
}
stack.Push(true);
}
public void Commit()
{
CheckConnection();
bool isTrans=(bool)stack.Peek();
if(!isTrans)
throw(new SqlScopeException("不能使用Commit,因为对应的一次调用不是BeginTransaction"));
stack.Pop();
if(stack.Count==0)
{
try
{
trans.Commit();
}
finally
{
Dispose();
}
}
}
public void Rollback()
{
CheckConnection();
bool isTrans=(bool)stack.Peek();
if(!isTrans)
throw(new SqlScopeException("不能使用Rollback,因为对应的一次调用不是BeginTransaction"));
stack.Pop();
if(stack.Count==0)
{
trans.Rollback("trans");
Dispose();
}
else
{
trans.Rollback("trans"+stack.Count.ToString());
}
} /// <summary>
/// 和EnterQuery对应,和BeginTransaction不同之处,是它不会启动Transaction
/// </summary>
public void EnterQuery()
{
if(stack==null)
{
OpenConnection(false);
}
stack.Push(false);
}
public void LeaveQuery()
{
CheckConnection();
bool isTrans=(bool)stack.Peek();
if(isTrans)
throw(new SqlScopeException("不能使用LeaveQuery,因为对应的一次调用不是EnterQuery"));
stack.Pop();
if(stack.Count==0)
{
Dispose();
}
}
}
}

解决方案 »

  1.   

    //by lostinet.com
    using System;
    using System.Data;
    using System.Data.SqlClient;namespace ct
    {
    class Class1
    {
    static string ConnectionString
    {
    get
    {
    return "server=(local);trusted_connection=true;database=northwind;";
    }
    } static void BuildTable()
    {
    using(SqlScope ss=new SqlScope(ConnectionString))
    {
    ss.BeginTransaction();
    using(SqlCommand cmd=ss.CreateCommand(
      @"
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[test]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[test]CREATE TABLE [dbo].[test] (
    [id] [int] IDENTITY (1, 1) NOT NULL ,
    [text] [nvarchar] (1000) COLLATE Chinese_PRC_CI_AS NOT NULL 
    ) ON [PRIMARY]ALTER TABLE [dbo].[test] WITH NOCHECK ADD 
    CONSTRAINT [PK_test] PRIMARY KEY  CLUSTERED 
    (
    [id]
    )  ON [PRIMARY] 
    "
      ))
    {
    cmd.ExecuteNonQuery();
    } ss.Commit(); //并不需要使用Rollback,因为SqlScope是在这里被创建的。
    //如果ss没有被提交,最后Dispose时会自动Rollback
    }
    }
    static int InsertText(SqlScope ss,string text)
    {
    using(SqlCommand cmd=ss.CreateCommand(
      @"
    SET NOCOUNT ON
    INSERT INTO test(text) VALUES(@text)
    SET NOCOUNT OFF
    SELECT SCOPE_IDENTITY();
    "
      ))
    {
    cmd.Parameters.Add("@text",SqlDbType.NVarChar,1000).Value=text;
    return Convert.ToInt32(cmd.ExecuteScalar());
    }
    }
    [STAThread]
    static void Main(string[] args)
    {
    BuildTable(); Console.WriteLine("开始ExecuteA");
    ExecuteA("Call ExecuteA In Main");
    Console.WriteLine();
    using(SqlScope ss=new SqlScope(ConnectionString))
    {
    ss.BeginTransaction(); //以下的调用是共用一个Connection和Transaction try
    {
    Console.WriteLine();
    Console.WriteLine("开始ExecuteB");
    ExecuteB(ss);
    }
    catch
    {
    }
    try
    {
    Console.WriteLine();
    Console.WriteLine("开始ExecuteC");
    ExecuteC(ss);
    }
    catch
    {
    }
    try
    {
    Console.WriteLine();
    Console.WriteLine("开始ExecuteD");
    ExecuteD(ss);
    }
    catch
    {
    } ss.Commit();
    } using(SqlScope ss=new SqlScope(ConnectionString))
    {
    //ss在这里并没有调用BeginTransaction
    //在ExecuteD里,不会产生事务。
    try
    {
    Console.WriteLine();
    Console.WriteLine("最后一次调用ExecuteD");
    ExecuteD(ss);
    }
    catch
    {
    }
    }
    } static void ExecuteA(string msg)
    {
    SqlScope ss=new SqlScope(ConnectionString);
    ss.BeginTransaction();
    try
    { int msgid=InsertText(ss,msg);
    Console.WriteLine("A msgid={0} OK",msgid); ExecuteB(ss); try
    {
    ExecuteC(ss);
    ExecuteD(ss);
    }
    catch
    {
    //忽略C,D的异常。
    } //到这里提交结果。
    ss.Commit();
    }
    catch(Exception x)
    {
    ss.Rollback(); Console.WriteLine("A异常 : "+x.Message);
    throw(x);
    }
    } static void ExecuteB(SqlScope ss)
    {
    ss.BeginTransaction();
    try
    { int msgid=InsertText(ss,null);//异常。text不能为NULL
    Console.WriteLine("B msgid={0} OK",msgid); ExecuteC(ss);
    ExecuteD(ss); ss.Commit();
    }
    catch(Exception x)
    {
    //异常后回滚 B 的操作,但是不影响调用 B 的外部程序。例如 Main 或 A
    ss.Rollback(); Console.WriteLine("B异常 : "+x.Message);
    }
    }
    static void ExecuteC(SqlScope ss)
    {
    ss.BeginTransaction();
    try
    {
    int msgid=InsertText(ss,"ExecuteC..");
    Console.WriteLine("C msgid={0} OK",msgid);
    //可以见到有C msgid={0} OK的输出。
    //但是因为下面D抛出了异常。所以后面的Rollback被调用了 ExecuteD(ss); ss.Commit();
    }
    catch(Exception x)
    {
    ss.Rollback(); Console.WriteLine("C异常 : "+x.Message);
    }
    }
    static void ExecuteD(SqlScope ss)
    {
    ss.EnterQuery();
    //try,finally是必须的。
    //必须保证调用了EnterQuery后能调用LeaveQuery try
    {
    DataSet ds=new DataSet(); using(SqlDataAdapter sda=ss.CreateAdapter("SELECT * FROM test WHERE id=2003"))
    {
    sda.Fill(ds);
    string text=ds.Tables[0].Rows[0]["text"].ToString();//异常。Rows.Count为0
    Console.WriteLine("D getmsg:{0}",text);
    } }
    catch(Exception x)
    {
    Console.WriteLine("D异常 : "+x.Message);
    throw(x);
    }
    finally
    {
    ss.LeaveQuery();
    }
    }
    }
    }
      

  2.   

    刚刚修改了一下//by lostinet.com
    using System;
    using System.Collections;
    using System.Data.SqlClient;namespace ct
    {
    public class SqlScopeException:Exception
    {
    public SqlScopeException(string message)
    :base(message)
    {
    }
    public SqlScopeException(string message,Exception innerException)
    :base(message,innerException)
    {
    }
    }
    /// <summary>
    /// 通过传递SqlScope,实现SqlConnection,SqlTransaction的创建,起用,传递和释放
    /// </summary>
    public class SqlScope:IDisposable
    {
    string connString;
    SqlConnection conn=null;
    SqlTransaction trans=null;
    Stack stack=null;
    int transPos=0; public SqlConnection Connection
    {
    get
    {
    CheckConnection();
    return conn;
    }
    }
    public SqlTransaction Transaction
    {
    get
    {
    CheckConnection();
    return trans;
    }
    }
    public string ConnectionString
    {
    get
    {
    return connString;
    }
    }
    static public implicit operator SqlConnection (SqlScope ss)
    {
    return ss.Connection;
    }
    static public implicit operator SqlTransaction (SqlScope ss)
    {
    return ss.Transaction;
    } public SqlScope(string ConnectionString)
    {
    if(ConnectionString==null)
    throw(new ArgumentNullException("ConnectionString"));
    connString=ConnectionString;
    }
    ~SqlScope()
    {
    Dispose();
    }
    public void Dispose()
    {
    transPos=0;
    stack=null;
    try
    {
    if(trans!=null)
    trans.Dispose();
    }
    finally
    {
    try
    {
    if(conn!=null)
    conn.Dispose();
    }
    finally
    {
    conn=null;
    trans=null;
    }
    }
    }
    void OpenConnection()
    {
    if(!IsClosed)
    throw(new SqlScopeException("Connection已经被打开!"));
    try
    {
    stack=new Stack();
    conn=new SqlConnection(connString);
    conn.Open();
    }
    catch
    {
    Dispose();
    throw;
    }
    }
    void CheckConnection()
    {
    if(IsClosed)
    throw(new SqlScopeException("Connection没有打开或者已经被关闭"));
    }
    public bool IsClosed
    {
    get
    {
    return stack==null;
    }
    }
    public SqlCommand CreateCommand(string commandText)
    {
    if(commandText==null)
    throw(new ArgumentNullException("commandText"));
    CheckConnection();
    return new SqlCommand(commandText,conn,trans);
    }
    public SqlDataAdapter CreateAdapter(string commandText)
    {
    if(commandText==null)
    throw(new ArgumentNullException("commandText"));
    CheckConnection();
    return new SqlDataAdapter(CreateCommand(commandText));
    }
    /// <summary>
    /// 和Commit或Rollback对应
    /// </summary>
    public void BeginTransaction()
    {
    if(IsClosed)
    {
    try
    {
    OpenConnection();
    trans=conn.BeginTransaction();
    transPos=0;
    }
    catch
    {
    Dispose();
    throw;
    }
    }
    else
    {
    if(trans==null)
    {
    try
    {
    trans=conn.BeginTransaction("trans");
    }
    catch
    {
    trans=null;
    throw;
    }
    transPos=stack.Count;
    }
    else
    {
    trans.Save("trans"+stack.Count.ToString());
    }
    }
    stack.Push(true);
    }
    public void Commit()
    {
    CheckConnection();
    bool isTrans=(bool)stack.Peek();
    if(!isTrans)
    throw(new SqlScopeException("不能使用Commit,因为对应的一次调用不是BeginTransaction"));
    int pos=stack.Count-1;
    if(pos==transPos)
    {
    trans.Commit();
    }
    stack.Pop();
    if(stack.Count==0)
    Dispose();
    }
    public void Rollback()
    {
    CheckConnection();
    bool isTrans=(bool)stack.Peek();
    if(!isTrans)
    throw(new SqlScopeException("不能使用Rollback,因为对应的一次调用不是BeginTransaction"));
    int pos=stack.Count-1;
    if(stack.Count==transPos)
    {
    trans.Rollback("trans");
    }
    else
    {
    trans.Rollback("trans"+pos.ToString());
    }
    stack.Pop();
    if(stack.Count==0)
    Dispose();
    } /// <summary>
    /// 和EnterQuery对应,和BeginTransaction不同之处,是它不会启动Transaction
    /// </summary>
    public void EnterQuery()
    {
    if(IsClosed)
    OpenConnection();
    stack.Push(false);
    }
    public void LeaveQuery()
    {
    CheckConnection();
    bool isTrans=(bool)stack.Peek();
    if(isTrans)
    throw(new SqlScopeException("不能使用LeaveQuery,因为对应的一次调用不是EnterQuery"));
    stack.Pop();
    if(stack.Count==0)
    Dispose();
    }
    }
    }
      

  3.   

    太深奥,看不太懂,看来得好好学习!!!
    学习ing!!!!
      

  4.   

    不错不错。我原来一直用参数方法传入Transaction对象,很烦琐,而且必须一开始设计的时候就要先考虑哪些需要事务处理并加上接口参数,假如原来逻辑发生变化的话就很不实用了。还是楼主高!!又学了一招,呵呵。
      

  5.   

    。。
    集成到页面后: using System;
    using System.Data.SqlClient;
    public interface ISqlScope:IDisposable
    {
    SqlConnection Connection
    {
    get;
    }
    SqlTransaction Transaction
    {
    get;
    } void BeginTransaction();
    void Commit();
    void Rollback(); void EnterQuery();
    void LeaveQuery(); SqlCommand CreateCommand(string cmdtext);
    SqlDataAdapter CreateAdapter(string cmdtext); SqlDataReader ExecuteReader(string cmdtext);
    void ExecuteNonQuery(string cmdtext);
    object ExecuteScalar(string cmdtext); string ExecuteString(string cmdtext);
    int ExecuteInt32(string cmdtext);
    double ExecuteDouble(string cmdtext);
    DateTime ExecuteDateTime(string cmdtext);
    }
      

  6.   

    using System;
    using System.Collections;
    using System.Data.SqlClient;
    using System.Web;
    using System.Web.UI; public class SqlScopeException:Exception
    {
    public SqlScopeException(string message)
    :base(message)
    {
    }
    public SqlScopeException(string message,Exception innerException)
    :base(message,innerException)
    {
    }
    } public class SqlScopePage : Page , ISqlScope
    {
    override protected void OnInit(EventArgs e)
    {
    //设置ConnectionString
    connString=E.ConnectionString;
    base.OnInit(e);
    }
    ~SqlScopePage()
    {
    DisposeConnection();
    }
    override public void Dispose()
    {
    base.Dispose();
    DisposeConnection();
    } string connString;
    SqlConnection conn=null;
    SqlTransaction trans=null;
    Stack stack=null;
    int transPos=0; public SqlConnection GetConnection()
    {
    CheckConnection();
    return conn;
    }
    public SqlTransaction GetTransaction()
    {
    CheckConnection();
    return trans;
    }
    SqlConnection ISqlScope.Connection
    {
    get
    {
    return GetConnection();
    }
    }
    SqlTransaction ISqlScope.Transaction
    {
    get
    {
    return GetTransaction();
    }
    }
    public string ConnectionString
    {
    get
    {
    return connString;
    }
    } void OpenConnection()
    {
    if(!IsClosed)
    throw(new SqlScopeException("Connection已经被打开!"));
    try
    {
    stack=new Stack();
    conn=new SqlConnection(connString);
    conn.Open();
    }
    catch
    {
    DisposeConnection();
    throw;
    }
    }
    void CheckConnection()
    {
    if(IsClosed)
    throw(new SqlScopeException("Connection没有打开或者已经被关闭"));
    }
    bool IsClosed
    {
    get
    {
    return stack==null;
    }
    }
    private void DisposeConnection()
    {
    transPos=0;
    stack=null;
    try
    {
    if(trans!=null)
    trans.Dispose();
    }
    finally
    {
    try
    {
    if(conn!=null)
    conn.Dispose();
    }
    finally
    {
    conn=null;
    trans=null;
    }
    }
    } public SqlCommand CreateCommand(string commandText)
    {
    if(commandText==null)
    throw(new ArgumentNullException("commandText"));
    CheckConnection();
    return new SqlCommand(commandText,conn,trans);
    }
    public SqlDataAdapter CreateAdapter(string commandText)
    {
    if(commandText==null)
    throw(new ArgumentNullException("commandText"));
    CheckConnection();
    return new SqlDataAdapter(CreateCommand(commandText));
    }
    public void ExecuteNonQuery(string cmdtext)
    {
    using(SqlCommand cmd=CreateCommand(cmdtext))
    {
    cmd.ExecuteNonQuery();
    }
    }
    public SqlDataReader ExecuteReader(string cmdtext)
    {
    using(SqlCommand cmd=CreateCommand(cmdtext))
    {
    return cmd.ExecuteReader();
    }
    }
    public object ExecuteScalar(string cmdtext)
    {
    using(SqlCommand cmd=CreateCommand(cmdtext))
    {
    return cmd.ExecuteScalar();
    }
    }
    public String ExecuteString(string cmdtext)
    {
    return Convert.ToString(ExecuteScalar(cmdtext));
    }
    public int ExecuteInt32(string cmdtext)
    {
    return Convert.ToInt32(ExecuteScalar(cmdtext));
    }
    public double ExecuteDouble(string cmdtext)
    {
    return Convert.ToDouble(ExecuteScalar(cmdtext));
    }
    public DateTime ExecuteDateTime(string cmdtext)
    {
    return Convert.ToDateTime(ExecuteScalar(cmdtext));
    }
    /// <summary>
    /// 和Commit或Rollback对应
    /// </summary>
    public void BeginTransaction()
    {
    if(IsClosed)
    {
    try
    {
    OpenConnection();
    trans=conn.BeginTransaction();
    transPos=0;
    }
    catch
    {
    DisposeConnection();
    throw;
    }
    }
    else
    {
    if(trans==null)
    {
    try
    {
    trans=conn.BeginTransaction("trans");
    }
    catch
    {
    trans=null;
    throw;
    }
    transPos=stack.Count;
    }
    else
    {
    trans.Save("trans"+stack.Count.ToString());
    }
    }
    stack.Push(true);
    }
    public void Commit()
    {
    CheckConnection();
    bool isTrans=(bool)stack.Peek();
    if(!isTrans)
    throw(new SqlScopeException("不能使用Commit,因为对应的一次调用不是BeginTransaction"));
    int pos=stack.Count-1;
    if(pos==transPos)
    {
    trans.Commit();
    }
    stack.Pop();
    if(stack.Count==0)
    DisposeConnection();
    }
    public void Rollback()
    {
    CheckConnection();
    bool isTrans=(bool)stack.Peek();
    if(!isTrans)
    throw(new SqlScopeException("不能使用Rollback,因为对应的一次调用不是BeginTransaction"));
    int pos=stack.Count-1;
    if(stack.Count==transPos)
    {
    trans.Rollback("trans");
    }
    else
    {
    trans.Rollback("trans"+pos.ToString());
    }
    stack.Pop();
    if(stack.Count==0)
    DisposeConnection();
    } /// <summary>
    /// 和EnterQuery对应,和BeginTransaction不同之处,是它不会启动Transaction
    /// 如果只进行SELECT时,即不需要COMMIT或ROLLBACK,可以用这个代替BeginTransaction
    /// </summary>
    public void EnterQuery()
    {
    if(IsClosed)
    OpenConnection();
    stack.Push(false);
    }
    public void LeaveQuery()
    {
    CheckConnection();
    bool isTrans=(bool)stack.Peek();
    if(isTrans)
    throw(new SqlScopeException("不能使用LeaveQuery,因为对应的一次调用不是EnterQuery"));
    stack.Pop();
    if(stack.Count==0)
    DisposeConnection();
    }
    }
      

  7.   

    哦。。置顶了??谢谢了。。:)下面是最近的修正。。已经用在一个比较复杂的项目里。
    暂时并没有发现错误。namespace XXXX
    {
    using System;
    using System.Collections;
    using System.Data.SqlClient;
    using System.Web;
    using System.Web.UI; public interface ISqlScope:IDisposable
    {
    SqlConnection Connection
    {
    get;
    }
    SqlTransaction Transaction
    {
    get;
    } void BeginTransaction();
    void Commit();
    void Rollback(); void EnterQuery();
    void LeaveQuery(); SqlCommand CreateCommand(string cmdtext);
    SqlDataAdapter CreateAdapter(string cmdtext); SqlDataReader ExecuteReader(string cmdtext);
    void ExecuteNonQuery(string cmdtext);
    object ExecuteScalar(string cmdtext); string ExecuteString(string cmdtext);
    int ExecuteInt32(string cmdtext);
    double ExecuteDouble(string cmdtext);
    DateTime ExecuteDateTime(string cmdtext);
    }
    public class SqlScopeException:Exception
    {
    public SqlScopeException(string message)
    :base(message)
    {
    }
    public SqlScopeException(string message,Exception innerException)
    :base(message,innerException)
    {
    }
    }
    public class SqlScopeProgrammingException:SqlScopeException
    {
    public SqlScopeProgrammingException(string message)
    :base(message)
    {
    LogException();
    }
    public SqlScopeProgrammingException(string message,Exception innerException)
    :base(message,innerException)
    {
    }
    public void LogException()
    {
    }
    } public class SqlScopePage : System.Web.UI.Page , ISqlScope
    {
    override protected void OnInit(EventArgs e)
    {
    //设置ConnectionString 
    connString="Server=(local);uid=sa;pwd=;database=";
    base.OnInit(e);
    }
    ~SqlScopePage()
    {
    DisposeConnection();
    }
    override public void Dispose()
    {
    base.Dispose();
    DisposeConnection();
    } string connString;
    SqlConnection conn=null;
    SqlTransaction trans=null;
    Stack stack=null;
    int transPos=0; public SqlConnection GetConnection()
    {
    CheckConnection();
    return conn;
    }
    public SqlTransaction GetTransaction()
    {
    CheckConnection();
    return trans;
    }
    SqlConnection ISqlScope.Connection
    {
    get
    {
    return GetConnection();
    }
    }
    SqlTransaction ISqlScope.Transaction
    {
    get
    {
    return GetTransaction();
    }
    }
    public string ConnectionString
    {
    get
    {
    return connString;
    }
    } void OpenConnection()
    {
    if(!IsClosed)
    throw(new SqlScopeProgrammingException("Connection已经被打开!"));
    try
    {
    stack=new Stack();
    conn=new SqlConnection(connString);
    conn.Open();
    }
    catch
    {
    DisposeConnection();
    throw;
    }
    }
    void CheckConnection()
    {
    if(IsClosed)
    throw(new SqlScopeException("Connection没有打开或者已经被关闭"));
    }
    bool IsClosed
    {
    get
    {
    return stack==null;
    }
    }
    private void DisposeConnection()
    {
    transPos=0;
    stack=null;
    try
    {
    if(trans!=null)
    trans.Dispose();
    }
    finally
    {
    try
    {
    if(conn!=null)
    conn.Dispose();
    }
    finally
    {
    conn=null;
    trans=null;
    }
    }
    } public SqlCommand CreateCommand(string commandText)
    {
    if(commandText==null)
    throw(new ArgumentNullException("commandText"));
    CheckConnection();
    return new SqlCommand(commandText,conn,trans);
    }
    public SqlDataAdapter CreateAdapter(string commandText)
    {
    if(commandText==null)
    throw(new ArgumentNullException("commandText"));
    CheckConnection();
    return new SqlDataAdapter(CreateCommand(commandText));
    }
    public void ExecuteNonQuery(string cmdtext)
    {
    using(SqlCommand cmd=CreateCommand(cmdtext))
    {
    cmd.ExecuteNonQuery();
    }
    }
    public SqlDataReader ExecuteReader(string cmdtext)
    {
    using(SqlCommand cmd=CreateCommand(cmdtext))
    {
    return cmd.ExecuteReader();
    }
    }
    public object ExecuteScalar(string cmdtext)
    {
    using(SqlCommand cmd=CreateCommand(cmdtext))
    {
    return cmd.ExecuteScalar();
    }
    }
    public String ExecuteString(string cmdtext)
    {
    return Convert.ToString(ExecuteScalar(cmdtext));
    }
    public int ExecuteInt32(string cmdtext)
    {
    return Convert.ToInt32(ExecuteScalar(cmdtext));
    }
    public double ExecuteDouble(string cmdtext)
    {
    return Convert.ToDouble(ExecuteScalar(cmdtext));
    }
    public DateTime ExecuteDateTime(string cmdtext)
    {
    return Convert.ToDateTime(ExecuteScalar(cmdtext));
    }
    /// <summary>
    /// 和Commit或Rollback对应
    /// </summary>
    public void BeginTransaction()
    {
    if(IsClosed)
    {
    try
    {
    OpenConnection();
    trans=conn.BeginTransaction("trans");
    transPos=0;
    }
    catch
    {
    DisposeConnection();
    throw;
    }
    }
    else
    {
    if(trans==null)
    {
    try
    {
    trans=conn.BeginTransaction("trans");
    }
    catch
    {
    trans=null;
    throw;
    }
    transPos=stack.Count;
    }
    else
    {
    trans.Save("trans"+stack.Count.ToString());
    }
    }
    stack.Push(true);
    }
    public void Commit()
    {
    CheckConnection();
    bool isTrans=(bool)stack.Peek();
    if(!isTrans)
    throw(new SqlScopeProgrammingException("不能使用Commit,因为对应的一次调用不是BeginTransaction"));
    int pos=stack.Count-1;
    if(pos==transPos)
    {
    trans.Commit();
    }
    stack.Pop();
    if(stack.Count==0)
    DisposeConnection();
    }
    public void Rollback()
    {
    CheckConnection();
    bool isTrans=(bool)stack.Peek();
    if(!isTrans)
    throw(new SqlScopeProgrammingException("不能使用Rollback,因为对应的一次调用不是BeginTransaction"));
    int pos=stack.Count-1;
    if(pos==transPos)
    {
    trans.Rollback("trans");
    }
    else
    {
    trans.Rollback("trans"+pos.ToString());
    }
    stack.Pop();
    if(stack.Count==0)
    DisposeConnection();
    } /// <summary>
    /// 和EnterQuery对应,和BeginTransaction不同之处,是它不会启动Transaction
    /// 如果只进行SELECT时,即不需要COMMIT或ROLLBACK,可以用这个代替BeginTransaction
    /// </summary>
    public void EnterQuery()
    {
    if(IsClosed)
    OpenConnection();
    stack.Push(false);
    }
    public void LeaveQuery()
    {
    CheckConnection();
    bool isTrans=(bool)stack.Peek();
    if(isTrans)
    throw(new SqlScopeProgrammingException("不能使用LeaveQuery,因为对应的一次调用不是EnterQuery"));
    stack.Pop();
    if(stack.Count==0)
    DisposeConnection();
    }
    }

    }
      

  8.   

    用法是,在xxx.aspx.cs等使用Page的地方,
    例如
    public class xxx:System.Web.UI.Page把System.Web.UI.Page替换为SqlScopePage
    那么SqlScopePage的子类都可以调用BeginTransaction(),Commit()了。
    把SqlScopePage以ISqlScope进行传递,
    可以达到和上面举的例子的效果。。例如常见的代码会变成这样:public void BindDataGrid()
    {
    DataSet ds=new DataSet(); this.EnterQuery();//打开连接(如果连接没有打开的话)
    try
    {//创建SqlDataAdapter
    using(SqlDataAdapter sda=this.CreateAdapter("select * from employees"))
    {
    sda.Fill(ds);
    }
    }
    finally
    {
    this.LeaveQuery();//释放连接(如果连接是在前面释放的话)
    }
    DataGrid1.DataSource=ds.Tables[0].DefaultView;
    DataGrid1.DataBind();
    }更加复杂的情况参考上面的例子。通过传递ISqlScope(在Page的方法里,就是this了)就OK了。
      

  9.   

    新增的下面的方法,也另程序编写更方便了。。
    SqlDataReader ExecuteReader(string cmdtext);
    void ExecuteNonQuery(string cmdtext);
    object ExecuteScalar(string cmdtext); string ExecuteString(string cmdtext);
    int ExecuteInt32(string cmdtext);
    double ExecuteDouble(string cmdtext);
    DateTime ExecuteDateTime(string cmdtext);
      

  10.   

    Hi,  Lostinet (NeverCodeBehind)(迷失网络)  
    我想请教一下,这样做的优势在哪里?如果单单要操作数据库的话,我也可以写一个数据访问层来简化sqlconnection等对象的生成啊。
      

  11.   

    to:cnuninet(www.helloaspx.com)
    这样做,可以把数据库连接和数据库操作分开来管理.
    分开管理的好处明显是,
    做数据操作的函数,只需要对数据库进行操作就好了。
    它没有必要知道数据库是在哪里被打开的。
    他的COMMIT,ROLLBACK都不会影响到外部调用者.
    --------------
    我的类设计出来,可以很简单地实现TRANSACTION的嵌套..
    即使很深层的事务提交成功了.
    只要外部的程序不调用COMMIT,那么整个事务都不会被提交。.如果按上面例子的写法,那么程序的行为,和SQL SERVER内置的隐式事务很像.
      

  12.   

    刚报道,来占个坑。
    楼主真是个强淫啊!!!
    虽然俺刚开始学ASP,现在是啥都看不懂,但是就冲您码的那么符号我也要向您致敬,顶一顶。
      

  13.   

    to Lostinet (NeverCodeBehind)(迷失网络):
        楼主的算法很值得学习,但从软件结构的角度来看,还是支持写一个数据访问层来简化sqlconnection等对象的生成的方法,在数据访问层中同样可以做到把数据库连接和数据库操作分开来管理.而且让WEB PAGE直接连数据库不是好的构思.对于楼主首帖提到的问题,我觉得用连接池来解决可能更好.
        不吝赐教