2009-04-16 22 views
64

Tôi có một đoạn mã liên quan đến nhiều lần chèn nhưng cần phải thực hiện phương thức submitchanges trước khi tôi kết thúc chèn vào các bảng khác để tôi có thể lấy được một Id. Tôi đã được tìm kiếm thông qua internet và couldnt tìm thấy làm thế nào để tạo ra một giao dịch trong LINQ để sql. Tôi đã đặt bình luận trong mã nơi tôi muốn giao dịch diễn ra.Làm thế nào để tạo một giao dịch LINQ to SQL?

var created = false; 
    try 
    { 
     var newCharacter = new Character(); 
     newCharacter.characterName = chracterName; 
     newCharacter.characterLevel = 1; 
     newCharacter.characterExperience = 0; 
     newCharacter.userUsername = userUsername; 
     newCharacter.characterClassID = ccslst[0].characterClassID; 
     //Open transaction 


      ydc.Characters.InsertOnSubmit(newCharacter); 
      ydc.SubmitChanges(); 

      foreach (var ccs in ccslst) 
      { 
       var cs = new CharacterStat(); 
       cs.statId = ccs.statID;       
       cs.statValue = ccs.statValue; 
       cs.characterID = newCharacter.characterID; 
       ydc.CharacterStats.InsertOnSubmit(cs); 
      }      


      var ccblst = ydc.ClassBodies.Where(cb => cb.characterClassID == newCharacter.characterClassID); 
      foreach (var ccb in ccblst) 
      { 
       var charBody = new CharacterBody(); 
       charBody.bodyId = ccb.bodyId; 
       charBody.bodyPartId = ccb.bodyPartId; 
       charBody.characterID = newCharacter.characterID; 
       ydc.CharacterBodies.InsertOnSubmit(charBody); 
      } 
      ydc.SubmitChanges();  
      created = true; 
     //Commit transaction 
     } 
     catch (Exception ex) 
     { 
      created = false; 
      //transaction Rollback;      
     } 
     return created; 

EDIT: Quên kể rằng ydc là DataContext của tôi

Trả lời

65

Bọc toàn bộ điều trong một TransactionScope. Hãy gọi transaction.Complete() vào thời điểm bạn muốn cam kết. Nếu mã thoát khỏi khối không có Complete() được gọi, giao dịch sẽ được khôi phục. Tuy nhiên, sau khi xem câu trả lời của @ s_ruchit và kiểm tra lại mã của bạn, bạn có thể viết lại điều này để không yêu cầu số TransactionScope. Ví dụ đầu tiên sử dụng mã số TransactionScope cùng với mã của bạn. Ví dụ thứ hai làm cho một số thay đổi nhỏ, nhưng hoàn thành cùng một mục đích.

Nơi bạn cần sử dụng TransactionScope là khi bạn đang đọc giá trị từ cơ sở dữ liệu và sử dụng nó để đặt giá trị mới trên đối tượng đang được thêm. Trong trường hợp này, giao dịch LINQ sẽ không bao gồm lần đọc đầu tiên, chỉ sau lần gửi giá trị mới. Vì bạn đang sử dụng giá trị từ giá trị đọc để tính toán giá trị mới cho ghi, bạn cần đọc để được bao bọc trong cùng một giao dịch để đảm bảo rằng một trình đọc khác không tính cùng giá trị và giảm bớt thay đổi của bạn. Trong trường hợp của bạn, bạn chỉ đang viết để giao dịch LINQ tiêu chuẩn sẽ hoạt động.

Ví dụ 1:

var created = false; 

using (var transaction = new TransactionScope()) 
{ 
    try 
    { 
     var newCharacter = new Character(); 
     newCharacter.characterName = chracterName; 
     newCharacter.characterLevel = 1; 
     newCharacter.characterExperience = 0; 
     newCharacter.userUsername = userUsername; 
     newCharacter.characterClassID = ccslst[0].characterClassID; 

     ydc.Characters.InsertOnSubmit(newCharacter); 
     ydc.SubmitChanges(); 

     foreach (var ccs in ccslst) 
     { 
      var cs = new CharacterStat(); 
      cs.statId = ccs.statID;       
      cs.statValue = ccs.statValue; 
      cs.characterID = newCharacter.characterID; 
      ydc.CharacterStats.InsertOnSubmit(cs); 
     }      

     var ccblst = ydc.ClassBodies.Where(cb => cb.characterClassID == newCharacter.characterClassID); 
     foreach (var ccb in ccblst) 
     { 
      var charBody = new CharacterBody(); 
      charBody.bodyId = ccb.bodyId; 
      charBody.bodyPartId = ccb.bodyPartId; 
      charBody.characterID = newCharacter.characterID; 
      ydc.CharacterBodies.InsertOnSubmit(charBody); 
     } 
     ydc.SubmitChanges();  
     created = true; 

     transaction.Complete(); 
    } 
    catch (Exception ex) 
    { 
     created = false; 
    } 
} 
return created; 

Ví dụ 2:

try 
    { 
     var newCharacter = new Character(); 
     newCharacter.characterName = chracterName; 
     newCharacter.characterLevel = 1; 
     newCharacter.characterExperience = 0; 
     newCharacter.userUsername = userUsername; 
     newCharacter.characterClassID = ccslst[0].characterClassID; 

     ydc.Characters.InsertOnSubmit(newCharacter); 

     foreach (var ccs in ccslst) 
     { 
      var cs = new CharacterStat(); 
      cs.statId = ccs.statID;       
      cs.statValue = ccs.statValue; 
      newCharacter.CharacterStats.Add(cs); 
     }      

     var ccblst = ydc.ClassBodies.Where(cb => cb.characterClassID == newCharacter.characterClassID); 
     foreach (var ccb in ccblst) 
     { 
      var charBody = new CharacterBody(); 
      charBody.bodyId = ccb.bodyId; 
      charBody.bodyPartId = ccb.bodyPartId; 
      newCharacter.CharacterBodies.Add(charBody); 
     } 
     ydc.SubmitChanges();  
     created = true; 
    } 
    catch (Exception ex) 
    { 
     created = false; 
    } 
+0

Không chắc về cú pháp, tôi đã đặt mã của tôi trong phạm vi này: sử dụng (TransactionScope ts = new TransactionScope()) { // mã của tôi } – Drahcir

+0

Tôi đã thêm mã vào mã của bạn và được dán làm ví dụ. – tvanfosson

+0

Nó hoạt động, nhờ – Drahcir

38

Bạn không cần phải làm thực hiện giao dịch rõ ràng khi sử dụng LINQ to SQL. Tất cả các hoạt động DB được bao bọc trong một giao dịch theo mặc định.

Ex:

AppDataContext db = new AppDataContext(); 

<In memory operation 1 on db> 
<In memory operation 2 on db> 
<In memory operation 3 on db> 
<In memory operation 4 on db> 

db.SubmitChanges(); 

Tất cả các hoạt động giữa db DataContext khởi và db.SubmitChanges() được quấn quanh một giao dịch cơ sở dữ liệu của Net đảm bảo cơ sở dữ liệu của bạn sẽ được ở phù hợp và có tính toàn vẹn tài sản duy trì trên bảng.

đã đọc một bài báo By Scott Guthriehere: - http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx

+0

Nhưng cần một ID đã được tạo ra trong lần gửi thay đổi đầu tiên, không biết cách khác để thu thập id. – Drahcir

+3

Truy cập bài viết do ScottGu viết. Bạn có thể liên kết mà không có ID. Đó là vẻ đẹp của LINQ-to-SQL. Nếu bạn không làm như vậy, bạn sẽ không tận dụng Linq-To-Sql. Tôi khuyên bạn nên đọc bài viết của ScottGu. Bạn có thể tìm thấy liên kết trong Câu trả lời của tôi. –

+0

Có. Có vẻ như bạn có thể viết lại điều này để không yêu cầu giao dịch bên ngoài. Tôi sẽ cập nhật câu trả lời của mình. – tvanfosson

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