Entity Framework and Transaction Scope (LINQ, Entity Framework)       | 
   
 
			  
			  
                Entity Framework and Try Catch Exception (LINQ, Entity Framework)  การใช้งาน Transaction Scope ค่อนข้างจะมีความสำคัญกับ Application ที่ต้องการความถูกต้องของการทำงาน โดยเมื่อมีการเรียกใช้งาน Transaction รายการข้อมูลที่ Insert, Update และ Delete จะยังอยู่แค่ใน Temp ยังไม่ได้มีการกระทำลงใน Table จริง ๆ ทั้งนี้เมื่อมีการ Error เกิดขึ้นในขั้นตอนใดขั้นตอนหนึ่ง เราสามารถที่จะยกเลิกรายการ (Rollback) ข้อมูลทั้งหมดที่กระทำลงไป หรือในกรณีที่โปรแกรมทำงานราบรื่นไม่มีข้อผิดพลาดใด ๆ เกิดขึ้นก็ให้โปรแกรม Commit ข้อมูลถือว่าเป็นการเสร็จสิ้นกระบวนการใช้ Transaction 
 
ในการใช้ Transaction เมื่อมีการ Open Transaction แล้ว และตามด้วยเปิด Connection รายการกระทำกับข้อมูลหลังจากนี้ จะต้องอยู่ภายใต้ Connection ตัวเดียวกัน ในเคสนี้เราจะเปิด Connection ได้แค่ครั้งเดียวเท่านั้น จะไม่สามารถเปิด Connection  ขึ้นมาได้ ฉะนั้นในกรณ๊ที่มี Method ย่อยอื่น ๆ ที่เรียกใช้ Entity เราจะต้องทำการส่งค่า Connection นี้ไปใช้งานใน Method นั้น ๆ ด้วย 
 
Note!! เป็นข้อข้องใจของใครหลาย ๆ คนว่าในกรณีที่ใช้ Transaction เมื่อเกิดการ Insert , Update และ Delete ซึ่งจะยังไม่มีการ Commit ข้อมูลลงใน Table จริง ๆ แล้วในกรณีที่เกิด Query หลังจากนั้น เช่น ใน Transaction  มีการแก้ไขข้อมูลนั้น ๆ ไปแล้ว แล้วใน Statement ถัดมามีการ Query ข้อมูลนั้นมาใช้ มันจะเป็นข้อมูลก่อนการแก้ไข หรือ เป็นข้อมูลที่ถูกแก้ไขในระหว่างการทำงานของ Transaction  
คำตอบคือ!!  เป็นข้อมูลใหม่ที่เกิดในช่วงระหว่าง Transaction นั่นหมายถึงว่าใน Transaction มีการกระทำอะไรลงไป แม้ยังไม่ได้มีการ Commit เมื่อเรา Query ข้อมูลช่วงนั้น ๆ กลับมาใช้ใหม่ ก็จะได้ข้อมูลใหม่ที่เกิดในช่วง Transaction  
 
Transaction Scope Syntax (C#) 
           using (TransactionScope tran = new TransactionScope())
            {
                // Create new entities from Entities
                using (var db = new myDatabaseEntities())
                {
                    db.Database.Connection.Open();
                    try
                    {
                        // Statement
                        // Statement
                        // Statement
                        db.SaveChanges();
                        tran.Complete();
                    }
                    catch (Exception ex)
                    {                
                        // ex.InnerException.InnerException.Message
                    }
                    finally
                    {
                        db.Database.Connection.Close();
                        db.Dispose();
                        tran.Dispose();
                    }
                }
            }
Transaction Scope Syntax (VB.Net) 
        Using tran As New TransactionScope()
            ' Create new entities from Entities
            Using db = New myDatabaseEntities()
                db.Database.Connection.Open()
                Try
                    ' Statement
                    ' Statement
                    ' Statement
                    db.SaveChanges()
                    tran.Complete()
                    ' ex.InnerException.InnerException.Message
                Catch ex As Exception
                Finally
                    db.Database.Connection.Close()
                    db.Dispose()
                    tran.Dispose()
                End Try
            End Using
        End Using
 
 
 
 
Example 1 :  การ Insert ข้อมูลแบบปกติโดยไม่ใช่ Transaction 
 
  
 
ใน Table มีข้อมูลของ C006 อยู่แล้ว แต่จะลอง Insert ข้อมูลใหม่โดยมี C005 และ C006 
 
Code (C#) 
        private void frmMain_Load(object sender, EventArgs e)
        {        
             // Create new entities from Entities
            using (var db = new myDatabaseEntities())
            {
                try
                {
                    // Insert Statement 1
                    db.CUSTOMER.Add(new CUSTOMER()
                    {
                        CUSTOMER_ID = "C005",
                        NAME = "Rut Wisarut",
                        EMAIL = "[email protected]",
                        COUNTRY_CODE = "TH",
                        BUDGET = 5000000,
                        USED = 0,
                    });
                    db.SaveChanges();
                    // Insert Statement 2
                    db.CUSTOMER.Add(new CUSTOMER()
                    {
                        CUSTOMER_ID = "C006",
                        NAME = "Fun Wipa",
                        EMAIL = "[email protected]",
                        COUNTRY_CODE = "UK",
                        BUDGET = 7000000,
                        USED = 0,
                    });
                    db.SaveChanges();
                }
                catch (DataException ex)
                {
                    MessageBox.Show(ex.InnerException.InnerException.Message);
                }
            }
        }
Code (VB.Net) 
   Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' Create new entities from Entities
        Using db = New myDatabaseEntities()
            Try
                ' Insert Statement 1
                db.CUSTOMER.Add(New CUSTOMER() With { _
                     .CUSTOMER_ID = "C005", _
                     .NAME = "Rut Wisarut", _
                     .EMAIL = "[email protected]", _
                     .COUNTRY_CODE = "TH", _
                     .BUDGET = 5000000, _
                     .USED = 0 _
                })
                db.SaveChanges()
                ' Insert Statement 2
                db.CUSTOMER.Add(New CUSTOMER() With { _
                     .CUSTOMER_ID = "C006", _
                     .NAME = "Fun Wipa", _
                     .EMAIL = "[email protected]", _
                     .COUNTRY_CODE = "UK", _
                     .BUDGET = 7000000, _
                     .USED = 0 _
                })
                db.SaveChanges()
            Catch ex As DataException
                MessageBox.Show(ex.InnerException.InnerException.Message)
            End Try
        End Using
    End Sub
 
Screenshot 
 
  
 
แสดง Error ในขณะที่กำลังทำงาน 
 
  
 
แต่จะเห็นว่าในขณะนี้โปรแกรม Error มีการ Insert ข้อมูลลงไปใน 1 รายการ 
 
 
Example 2 :  การ Insert ข้อมูลโดยใช้ Transaction Scope 
 
  
 
Add Reference ของ System.Transaction เข้ามาใน Project 
 
ในการเรียกใช้งาน Transaction จะต้องทำการ using หรือ Import ตัว System.Transactions 
 
Code (C#) 
        private void frmMain_Load(object sender, EventArgs e)
        {
            using (TransactionScope tran = new TransactionScope())
            {
                // Create new entities from Entities
                using (var db = new myDatabaseEntities())
                {
                    db.Database.Connection.Open();
                    try
                    {
                        // Insert Statement 1
                        db.CUSTOMER.Add(new CUSTOMER()
                        {
                            CUSTOMER_ID = "C005",
                            NAME = "Rut Wisarut",
                            EMAIL = "[email protected]",
                            COUNTRY_CODE = "TH",
                            BUDGET = 5000000,
                            USED = 0,
                        });
                        // Insert Statement 2
                        db.CUSTOMER.Add(new CUSTOMER()
                        {
                            CUSTOMER_ID = "C006",
                            NAME = "Fun Wipa",
                            EMAIL = "[email protected]",
                            COUNTRY_CODE = "UK",
                            BUDGET = 7000000,
                            USED = 0,
                        });
                        db.SaveChanges();
                        tran.Complete();
                    }
                    catch (Exception ex)
                    {                
                        MessageBox.Show(ex.InnerException.InnerException.Message);
                    }
                    finally
                    {
                        db.Database.Connection.Close();
                        db.Dispose();
                        tran.Dispose();
                    }
                }
            }
        }
Code (VB.Net) 
    Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Using tran As New TransactionScope()
            ' Create new entities from Entities
            Using db = New myDatabaseEntities()
                db.Database.Connection.Open()
                Try
                    ' Insert Statement 1
                    db.CUSTOMER.Add(New CUSTOMER() With { _
                        .CUSTOMER_ID = "C005", _
                        .NAME = "Rut Wisarut", _
                        .EMAIL = "[email protected]", _
                        .COUNTRY_CODE = "TH", _
                        .BUDGET = 5000000, _
                        .USED = 0 _
                    })
                    ' Insert Statement 2
                    db.CUSTOMER.Add(New CUSTOMER() With { _
                        .CUSTOMER_ID = "C006", _
                        .NAME = "Fun Wipa", _
                        .EMAIL = "[email protected]", _
                        .COUNTRY_CODE = "UK", _
                        .BUDGET = 7000000, _
                        .USED = 0 _
                    })
                    db.SaveChanges()
                    tran.Complete()
                Catch ex As Exception
                    MessageBox.Show(ex.InnerException.InnerException.Message)
                Finally
                    db.Database.Connection.Close()
                    db.Dispose()
                    tran.Dispose()
                End Try
            End Using
        End Using
    End Sub
 
Screenshot 
 
  
 
จากตัวอย่างใน Example 2 นี้จะมีการใช้ Transaction มาควบคุมการทำงาน ซึ่งในเคสนี้จะมี Error และการ Insert ข้อมูลที่ได้ Insert ไปแล้วนั้นจะไม่มีการ Commit ลงใน Table 
 
 
 
ของแถม ตัวอย่างนี้จะมีในส่วนของ Entity Framework กับ Transaction และการใช้คำสั่ง SqlConnection  โดยเรียกใช้ Connection ของ Entity Framework และการใช้ Transaction ของ SqlConnection  ซึ่งทั้ง 2 Transaction นี้จะใช้ Connection ตัวเดียวกัน  
 
Code (C#) 
        private void frmMain_Load(object sender, EventArgs e)
        {
            using (TransactionScope tran = new TransactionScope())
            {
                // Create new entities from Entities
                using (var db = new myDatabaseEntities())
                {
                    db.Database.Connection.Open();
                    EntityConnection ec = (EntityConnection)db.Database.Connection;
                    SqlConnection sqlCon = (SqlConnection)ec.StoreConnection;
                    SqlTransaction sqlTrans = sqlCon.BeginTransaction();
                    try
                    {
                        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlCon, SqlBulkCopyOptions.Default, sqlTrans))
                        {
                            // Statement
                        }
                        // ExecuteNonQuery
                        string strSQL = "INSERT INTO customer (CustomerID,Name,Email,CountryCode,Budget,Used) " +
                            " VALUES ('C005','Weerachai Nukitram','[email protected]','TH','2000000','1000000')";
                        SqlCommand objCmd = new SqlCommand();
                        objCmd.Connection = sqlCon;
                        objCmd.CommandType = CommandType.Text;
                        objCmd.CommandText = strSQL;
                        objCmd.ExecuteNonQuery();
                        // Insert Statement 2
                        db.CUSTOMER.Add(new CUSTOMER()
                        {
                            CUSTOMER_ID = "C006",
                            NAME = "Fun Wipa",
                            EMAIL = "[email protected]",
                            COUNTRY_CODE = "UK",
                            BUDGET = 7000000,
                            USED = 0,
                        });
                        db.SaveChanges();
                        tran.Complete();
                        sqlTrans.Commit();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.InnerException.InnerException.Message);
                    }
                    finally
                    {
                        db.Database.Connection.Close();
                        db.Dispose();
                        tran.Dispose();
                        sqlTrans.Dispose();
                    }
                }
            }
        }
Code (VB.Net) 
   Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Using tran As New TransactionScope()
            ' Create new entities from Entities
            Using db = New myDatabaseEntities()
                db.Database.Connection.Open()
                Dim ec As EntityConnection = DirectCast(db.Database.Connection, EntityConnection)
                Dim sqlCon As SqlConnection = DirectCast(ec.StoreConnection, SqlConnection)
                Dim sqlTrans As SqlTransaction = sqlCon.BeginTransaction()
                Try
                    ' Statement
                    Using bulkCopy As New SqlBulkCopy(sqlCon, SqlBulkCopyOptions.[Default], sqlTrans)
                    End Using
                    ' ExecuteNonQuery
                    Dim strSQL As String = "INSERT INTO customer (CustomerID,Name,Email,CountryCode,Budget,Used) " + " VALUES ('C005','Weerachai Nukitram','[email protected]','TH','2000000','1000000')"
                    Dim objCmd As New SqlCommand()
                    objCmd.Connection = sqlCon
                    objCmd.CommandType = CommandType.Text
                    objCmd.CommandText = strSQL
                    objCmd.ExecuteNonQuery()
                    ' Insert Statement 2
                    db.CUSTOMER.Add(New CUSTOMER() With { _
                        .CUSTOMER_ID = "C006", _
                        .NAME = "Fun Wipa", _
                        .EMAIL = "[email protected]", _
                        .COUNTRY_CODE = "UK", _
                        .BUDGET = 7000000, _
                        .USED = 0 _
                    })
                    db.SaveChanges()
                    tran.Complete()
                    sqlTrans.Commit()
                Catch ex As Exception
                    MessageBox.Show(ex.InnerException.InnerException.Message)
                Finally
                    db.Database.Connection.Close()
                    db.Dispose()
                    tran.Dispose()
                    sqlTrans.Dispose()
                End Try
            End Using
        End Using
    End Sub
 
ในการเรียกใช้งาน Transaction จะต้องทำการ using หรือ Import ตัว System.Transactions , System.Data.SqlClient และ System.Data.EntityClient              
  
              			
			  
								  
			  
  
                          
  | 
           
          
            
			  ช่วยกันสนับสนุนรักษาเว็บไซต์ความรู้แห่งนี้ไว้ด้วยการสนับสนุน Source Code 2.0 ของทีมงานไทยครีเอท 
              | 
           
          
 
       
		 
					
        
          
            
                
                   | 
                 
                
                  |   | 
                  By :  | 
                  ThaiCreate.Com Team (บทความเป็นลิขสิทธิ์ของเว็บไทยครีเอทห้ามนำเผยแพร่ ณ เว็บไซต์อื่น ๆ)  | 
                 
                
                  |   | 
                  Score Rating :  | 
                  
				    				   | 
                    | 
                 
                
                  |   | 
                  Create/Update Date :  | 
                  
                    2015-10-02 21:18:20            /
            2017-03-24 22:55:42 | 
                 
				
				
				                
                  |   | 
                  Download :  | 
                   
				 No files				   | 
                 
				              | 
           
         
		
      
         
           
            
            
              
                | 
               
                   Sponsored Links / Related |  
              | 
         
        
                        | 
          
		  
		   | 
         
         
          |             
		  
	
      
     | 
     
 
 
		  
         | 
		
          
		   
		  
              
      
     |