2011-11-26 33 views
8

Xin chào Tôi đang cố gắng sử dụng các giao dịch cùng với Khuôn khổ thực thể. Với rất nhiều thông tin có sẵn trực tuyến trên các cách khác nhau để thực hiện các giao dịch, tôi phải nói rằng tôi hơi bối rối một cách đúng đắn. Tôi có một cơ sở dữ liệu ví dụ với hai bảng Employee and Company. Bảng Employee có khóa ngoài tham chiếu đến Id công ty. Xem xét tôi muốn thực hiện một giao dịch mà tôi chèn một bản ghi vào bảng Company và sau đó một bản ghi vào bảng Employee và tôi muốn làm điều này để các bản ghi được chèn chỉ khi cả hai đều thành công, tôi có đoạn mã sau.Hiểu giao dịch trong khung thực thể

public void addCompanyToDatabase() 
    { 
     using (var context = new myTestEntities()) 
     { 
      context.Connection.Open(); //added this as was getting the underlying 
      //provider failed to open 
      using (TransactionScope scope = new TransactionScope()) 
      { 
       try 
       { 
        Company c = new Company(); 
        c.Name = "xyz"; 
        context.Companies.AddObject(c); 
        context.SaveChanges(); 

        //int a = 0; 
        //int b = 5/a; 

        Employee e = new Employee(); 
        e.Age = 15; 
        e.Name = "James"; 
        e.CompanyId = c.Id; 
        context.Employees.AddObject(e); 
        context.SaveChanges(); 

        scope.Complete(); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine("Exception Occurred"); 
       } 
      } 
     } 
    } 

Tôi muốn biết đây có phải là cách thực hiện giao dịch đúng hay không. Nếu đó là thì việc sử dụng các hàm SaveChanges(false) và các chức năng scope.AcceptAllChanges() là gì. Bất kỳ thông tin có thể hữu ích.

Trả lời

14

Trong trường hợp của bạn, bạn không cần phải quản lý bất kỳ kết nối hoặc giao dịch nào: Entity Framework sẽ thực hiện việc này cho bạn. Khi bạn không cung cấp cho EF kết nối mở (nhưng với chuỗi kết nối), nó sẽ mở một kết nối và bắt đầu một giao dịch trong khi gọi đến context.SaveChanges(). Khi có điều gì đó thất bại trong suốt cuộc gọi đó, giao dịch sẽ được khôi phục.

Nói cách khác, phương pháp của bạn chỉ có thể trông như thế này:

public void addCompanyToDatabase() 
{ 
    using (var context = new myTestEntities()) 
    { 
     Company c = new Company(); 
     c.Name = "xyz"; 
     context.Companies.AddObject(c); 

     Employee e = new Employee(); 
     e.Age = 15; 
     e.Name = "James"; 
     e.CompanyId = c.Id; 
     context.Employees.AddObject(e); 

     // Only call SaveChanges last. 
     context.SaveChanges(); 
    } 
} 
+0

Điều đó có ý nghĩa trong trường hợp ví dụ của tôi. Bạn có thể cho tôi một ví dụ mà tôi sẽ cần một giao dịch không? và liệu mã tôi đã đề cập ở trên có phải là cách để thực hiện giao dịch không? Tôi đoán việc cập nhật các bản ghi với hai ngữ cảnh khác nhau là một kịch bản. – nighthawk457

+1

Trường hợp phổ biến nhất mà tôi gặp phải khiến bạn cần một giao dịch, là khi bạn cần gọi 'SaveChanges' nhiều lần. Điều này có thể xảy ra khi bạn cần id (cơ sở dữ liệu được tạo) của đối tượng mới hoặc khi bạn cần buộc ORM thực thi các thao tác theo thứ tự nhất định (ví dụ, LINQ to SQL có xu hướng sắp xếp lại xóa sau khi chèn, nhưng điều này có thể kích hoạt ngoại lệ ràng buộc cơ sở dữ liệu). – Steven

+3

Trong mọi trường hợp, vẫn không cần sử dụng 'TransactionScope'. Nếu bạn cần một 'TransactionScope' bởi vì bạn cần các hoạt động để được nguyên tử trên nhiều cơ sở dữ liệu, bạn có thể có một lỗ hổng thiết kế trong hệ thống của bạn. Tôi sử dụng 'TransactionScope' hoàn toàn cho các bài kiểm tra tích hợp tự động của tôi. Chỉ cần rap mã gọi trong 'TransactionScope' và bạn có thể chắc chắn rằng tất cả các thay đổi (cơ sở dữ liệu) được khôi phục vào cuối bài kiểm tra, mà không phải thay đổi bất kỳ mã nào cho điều này. – Steven

0

1-này dịch vụ (tôi nghĩ rằng dịch vụ giao dịch) phải chạy trong ứng dụng để hỗ trợ TransactionScope

2 -Sử dụng khi bạn có kéo hoặc nhiều cơ sở dữ liệu trong ứng dụng của bạn và bạn muốn tất cả cơ sở dữ liệu cập nhật giao dịch (chẳng hạn như thay đổi chuỗi kết nối của ngữ cảnh của bạn).

3-Khi bạn có cơ sở dữ liệu, hãy sử dụng SaveChanges() để thực hiện giao dịch trong nội bộ.

Các vấn đề liên quan