2017-04-25 71 views
0

碼復位SQL表的數據:如何,而在交易

BusinessLayer

// an array of type int with 3 values is present 
foreach(var item in list) 
{ 
    //Pseudocode incoming 
    Query_DoSomethingWithItem(item.Identifier, myArray) 
} 

DAL

DoSomethingWithItem(long id, int[] theArray) 
{ 
    using(var scope = new TransactionScope() 
    { 
     // using SqlConnection 

     // fill command-parameter which makes use of a user-defined-table, which represents an array of integers. 
     // Important: The underlying stored_proc WRITES to database 

     conn.Open(); 
     command.ExecuteNonQuery(); 
     scope.Complete(); 
    } 
} 

=>問題是,它運行完美在第一次運行中,但在第二次運行中,UDT的int數組已經從第一次執行中填充了值。

如何在首次運行後重置UDT的數據?

我試着用TransactionScope.RequiresNew但沒有區別。

編輯:這就是我想實現:

表:對象[的ObjectId,...]

表:項目[的ObjectId(FK),索引]

UDT:IntegerArrray

N項目可以屬於1個對象。

回答

0

爲什麼不只是返回你需要的而不是修改現有的集合呢?僞代碼如下:

// an array of type int with 3 values is present 
foreach(var item in list) 
{ 
    //Pseudocode incoming 
    Query_DoSomethingWithItem(item.Identifier, myArray) 
} 

int[] DoSomethingWithItem(long id) 
{ 
    var result = new List<int>(); 
    using(var scope = new TransactionScope() 
    { 
    using(var con = new SqlConnection()) 
    { 
     using(var cmd = new sqlcommand()) 
     { 
     con.Open();  
     cmd.ExecuteNonQuery();  
     // fill your list of integers.   
     scope.Complete(); 
     } 
    } 
    } 
    return result.ToArray(); 
} 
+0

我不清楚這個問題,我必須指出它是WRITE,而不是讀取數據庫的訪問。第二次運行(foreach循環中的第二項)cmd.ExecuteNonQuery()將失敗,因爲user-defined-table(整數數組)已經有值。 –

+0

我一直使用數據表來保存udt數據。不管你在DoSomethingWithItem中新建一個數據表。 – Steve

1

我們可能需要更多的上下文才能給出明智的答案。僞代碼並沒有精確地定義你所要做的。我們需要更多的代碼來理解爲什麼這些變量「被重用」。最有可能的猜測是事務範圍干擾了變量的重置,或者在下一個循環中丟失。

但是,從我所看到的,我可以這樣說。當我編寫軟件時,我傾向於避免在這種數據庫持久性/業務邏輯通信中循環數據集。

爲什麼?業務層負責將對象/數據移交給您的數據層(存儲庫,DAC,無論您想要調用它)還是期待某種響應。

這種反應可能是

  • 一切都變成了巨大的
  • 出了錯

業務層,然後將這些答案作出適當的反應。業務層不應該知道(或關心)該數據是如何持久存在的(比如循環數據)。它只是將整個數據集合交給數據層,並讓數據層在事務內部進行循環。

這將您的疑慮分爲: - 業務層關心將數據交給數據層,並對成功或失敗做出響應。數據層知道它將接收的數據的種類,以及如何最好地堅持它。

你的僞代碼可以重構,看起來像這樣

業務層:

public void DoSomethingWithData(list) { 
    Query_DoSomethingWithItem(list); 
} 

DAL:

public void Query_DoSomethingWithItem(List<item> list) 
{ 
    using(var scope = new TransactionScope() 
    { 

     // using SqlConnection 

     // fill command-parameter which makes use of a user-defined-table, which represents an array of integers. 

     conn.Open(); 
     foreach(var item in list) { 
      //initialise the myArray in here 
      command.ExecuteNonQuery(item, myArray); 
     } 
     scope.Complete(); 
    } 
} 

希望這是你所追求的。

+0

史密斯先生,謝謝你的回答。這是有道理的,是的。但對我而言,這並不「感覺」正確。因爲在循環內部,我還有一些額外的if以檢查項目是否合法。如果我將整個邏輯移動到DAL中,感覺就像我打破了層的意圖... –

+0

這是一個很好的觀點,是的,業務邏輯應該保留在業務層。在這種情況下,您可能會考慮在業務層中使用UnitOfWork樣式模式,或者可能將「if」邏輯移入存儲過程(如果適用)。 在上述情況下,我會確保將「if」規則應用於業務層中的數據(例如「如果這是真的,則將此項屬性更改爲X而不是Y」),然後在所有這些業務規則應用後交給DAL。 –

+0

然而,看看你的代碼,它對我來說沒有意義,爲什麼DAL層重用了以前的變量。這些類是靜態還是靜態方法?周圍的代碼肯定會幫助你得到一個非常可靠的答案。 –