ADO.NET使用方法和技巧

来源:网络时间:2011-06-23

  bool CheckProductWithReader( int ProductID )

  {

  using( SqlConnection conn = new SqlConnection(

  "server=(local);Integrated Security=SSPI;database=northwind") )

  {

  SqlCommand cmd = new SqlCommand("CheckProductExistsWithCount", conn );

  cmd.CommandType = CommandType.StoredProcedure;

  cmd.Parameters.Add("@ProductID", ProductID );

  cmd.Parameters["@ProductID"].Direction = ParameterDirection.Input;

  conn.Open();

  using( SqlDataReader reader = cmd.ExecuteReader(

  CommandBehavior.SingleResult ) )

  {

  if( reader.Read() )

  {

  return (reader.GetInt32(0) > 0);

  }

  return false;

  }

  }

  上述代码采用了以下存储过程。

  CREATE PROCEDURE CheckProductExistsWithCount

  @ProductID int

  AS

  SELECT COUNT(*) FROM Products

  WHERE ProductID = @ProductID

  GO

  如何编写 ADO.NET 手动事务处理代码

  以下代码显示了如何充分利用 SQL Server .NET 数据提供程序所提供的事务处理支持,通过事务来保护资金转帐操作。该操作在同一数据库中的两个帐户之间转移资金。

  public void TransferMoney( string toAccount, string fromAccount, decimal amount )

  {

  using ( SqlConnection conn = new SqlConnection(

  "server=(local);Integrated Security=SSPI;database=SimpleBank" ) )

  {

  SqlCommand cmdCredit = new SqlCommand("Credit", conn );

  cmdCredit.CommandType = CommandType.StoredProcedure;

  cmdCredit.Parameters.Add( new SqlParameter("@AccountNo", toAccount) );

  cmdCredit.Parameters.Add( new SqlParameter("@Amount", amount ));

  SqlCommand cmdDebit = new SqlCommand("Debit", conn );

  cmdDebit.CommandType = CommandType.StoredProcedure;

  cmdDebit.Parameters.Add( new SqlParameter("@AccountNo", fromAccount) );

  cmdDebit.Parameters.Add( new SqlParameter("@Amount", amount ));

  conn.Open();

  // Start a new transaction

  using ( SqlTransaction trans = conn.BeginTransaction() )

  {

  // Associate the two command objects with the same transaction

  cmdCredit.Transaction = trans;

  cmdDebit.Transaction = trans;

  try

  {

  cmdCredit.ExecuteNonQuery();

  cmdDebit.ExecuteNonQuery();

  // Both commands (credit and debit) were successful

  trans.Commit();

  }

  catch( Exception ex )

  {

  // transaction failed

  trans.Rollback();

  // log exception details . . .

  throw ex;

  }

  }

  }

  }

  如何使用 Transact-SQL 执行事务处理

  以下存储过程阐明了如何在 Transact-SQL 存储过程内部执行事务性资金转帐操作。

  CREATE PROCEDURE MoneyTransfer

  @FromAccount char(20),

  @ToAccount char(20),

  @Amount money

  AS

  BEGIN TRANSACTION

  -- PERFORM DEBIT OPERATION

  UPDATE Accounts

  SET Balance = Balance - @Amount

  WHERE AccountNumber = @FromAccount

  IF @@RowCount = 0

  BEGIN

  RAISERROR('Invalid From Account Number', 11, 1)

  GOTO ABORT

  END

  DECLARE @Balance money

  SELECT @Balance = Balance FROM ACCOUNTS

  WHERE AccountNumber = @FromAccount

  IF @BALANCE < 0

  BEGIN

  RAISERROR('Insufficient funds', 11, 1)

  GOTO ABORT

  END

  -- PERFORM CREDIT OPERATION

  UPDATE Accounts

  SET Balance = Balance + @Amount

  WHERE AccountNumber = @ToAccount

  IF @@RowCount = 0

  BEGIN

  RAISERROR('Invalid To Account Number', 11, 1)

  GOTO ABORT

  END

  COMMIT TRANSACTION

  RETURN 0

  ABORT:

  ROLLBACK TRANSACTION

  GO

  该存储过程使用 BEGIN TRANSACTION、COMMIT TRANSACTION 和 ROLLBACK TRANSACTION 语句来手动控制该事务。

  如何编写事务性 .NET 类

  以下示例代码显示了三个服务性 .NET 托管类,这些类经过配置以执行自动事务处理。每个类都使用 Transaction 属性进行了批注,该属性的值确定是否应该启动新的事务流,或者该对象是否应该共享其直接调用方的事务流。这些组件协同工作来执行银行资金转帐任务。Transfer 类被使用 RequiresNew 事务属性进行了配置,而 Debit 和 Credit 被使用 Required 进行了配置。结果,所有这三个对象在运行时都将共享同一事务。

  using System;

  using System.EnterpriseServices;

  [Transaction(TransactionOption.RequiresNew)]

  public class Transfer : ServicedComponent

  {

  [AutoComplete]

  public void Transfer( string toAccount,

  string fromAccount, decimal amount )

  {

  try

  {

  // Perform the debit operation

  Debit debit = new Debit();

  debit.DebitAccount( fromAccount, amount );

  // Perform the credit operation

  Credit credit = new Credit();

  credit.CreditAccount( toAccount, amount );

  }

  catch( SqlException sqlex )

  {

  // Handle and log exception details

  // Wrap and propagate the exception

  throw new TransferException( "Transfer Failure", sqlex );

  }

  }

  }

  [Transaction(TransactionOption.Required)]

  public class Credit : ServicedComponent

  {

  [AutoComplete]

  public void CreditAccount( string account, decimal amount )

  {

  try

  {

  using( SqlConnection conn = new SqlConnection(

  "Server=(local); Integrated Security=SSPI"; database="SimpleBank") )

  {

  SqlCommand cmd = new SqlCommand("Credit", conn );

  cmd.CommandType = CommandType.StoredProcedure;

  cmd.Parameters.Add( new SqlParameter("@AccountNo", account) );

  cmd.Parameters.Add( new SqlParameter("@Amount", amount ));

  conn.Open();

  cmd.ExecuteNonQuery();

  }

  }

  }catch( SqlException sqlex ){

  // Log exception details here

  throw; // Propagate exception

  }

  }

  [Transaction(TransactionOption.Required)]

  public class Debit : ServicedComponent

  {

  public void DebitAccount( string account, decimal amount )

  {

  try

  {

  using( SqlConnection conn = new SqlConnection(

  "Server=(local); Integrated Security=SSPI"; database="SimpleBank") )

  {

  SqlCommand cmd = new SqlCommand("Debit", conn );

  cmd.CommandType = CommandType.StoredProcedure;

  cmd.Parameters.Add( new SqlParameter("@AccountNo", account) );

  cmd.Parameters.Add( new SqlParameter("@Amount", amount ));

  conn.Open();

  cmd.ExecuteNonQuery();

  }

  }

  catch (SqlException sqlex)

  {

  // Log exception details here

  throw; // Propagate exception back to caller

  }

  }

  }

意见反馈
发表评论

最新评论(共0条)