0

I am currently working on a SharePoint 2013 project with custom application pages development. On one of those pages, there are multiple insert / update to database table operations. Here are the sample code I am working with:

Product.cs

class Product
{
    public int ProductId { get; set; };
    public string ProductName { get; set; };
}

Here is the helper class which handle CRUD of products:

ProductFacade.cs

class ProductFacade
{
    public static Product Save(Product productObject)
    {
        Product product;
        using(SqlConnection conn = new SqlConnection(DatabaseHelper.ConnectionString)) // The connection string is retrieved from other helper class
        {
            SqlCommand cmd = new SqlCommand("SaveProduct", conn);
            cmd.CommandType = CommandType.StoredProcedure;
            conn.Open();

            // Parameters setting and execute query operations here..
        }
        return product;
    }
}

In the application pages, I used the method like:

ApplicationPage.aspx.cs

public void SaveProducts()
{
    try
    {
        DataTable products = (DataTable)ViewState["Products"];
        if(products != null)
        {
            Product product;
            foreach(DataRow row in products.Rows)
            {
                product = new Product();
                product.ProductName = row["ProductName"].ToString();
                ProductFacade.Save(product);
            }
        }
    }
    catch(Exception ex)
    {
        LogHelper.WriteLog(Category.Unexpected, "Product Application Page", ex.Message + ", " + ex.StackTrace);
    }
}

All of the methods in that helper class work fine. But I am curious, how if I want to add transaction management, for example, if I want to add BeginTransaction, Commit, and Rollback operation on the above SaveProducts() method? Should I create and pass the SqlConnection object as a parameter to the ProductFacade.Save() method so it will be something like:

ProductFacade.cs

class ProductFacade
{
    public static Product Save(Product productObject, SqlConnection conn = null, SqlTransaction tran = null)
    {
        Product product;
        if(conn == null)
            conn = new SqlConnection(DatabaseHelper.ConnectionString);
        using(SqlCommand cmd = new SqlCommand("SaveProduct", conn))
        {
            if(tran != null)
                cmd.Transaction = tran;
            // The rest of the same code from before
        }
    }
}

And call the method with SqlConnection object passed like:

ApplicationPage.aspx.cs

public void SaveProducts()
{
    using(SqlConnection conn = new SqlConnection(DatabaseHelper.ConnectionString))
    {
        conn.Open();
        SqlTransaction transaction = conn.BeginTransaction();
        try
        {
            DataTable products = (DataTable)ViewState["Products"];
            if(products != null)
            {
                Product product;
                foreach(DataRow row in products.Rows)
                {
                    product = new Product();
                    product.ProductName = row["ProductName"].ToString();
                    ProductFacade.Save(product, conn, transaction);
                }
            }
            transaction.Commit();
        }
        catch(Exception ex)
        {
            transaction.RollBack();
            LogHelper.WriteLog(Category.Unexpected, "Product Application Page", ex.Message + ", " + ex.StackTrace);
        }
    }
}

Really appreciate any thoughts on this.

Andy Wijaya
  • 158
  • 8
  • Sqlconnection will be closed in the finally block of the try catch when the compiler works its magic. :) it will write it's own finally in that calls the dispose of connection, so any path through the code will be terminated. – Chris Watts Jun 23 '17 at 04:10
  • Here is a similar question: https://stackoverflow.com/questions/18588049/sqlconnection-close-inside-using-statement – Chris Watts Jun 23 '17 at 04:12
  • Thats not exactly what I am asking. What I am asking is, whether I should use the above method when I want to add BeginTransaction, Commit, and Rollback functionality to my code, or any other better approaches or methods. – Andy Wijaya Jun 23 '17 at 04:14
  • If you are asking for better way to implement then you should ask this question on https://codereview.stackexchange.com/. :) – Jenish Rabadiya Jun 23 '17 at 04:21
  • Oh, okay. Thank you Jenish. I will post my question there. – Andy Wijaya Jun 23 '17 at 04:21
  • Ahh sorry, saw what you were trying to do and jumped to conclusions. Apologies – Chris Watts Jun 23 '17 at 05:21

0 Answers0