2017-04-25 39 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层重用了以前的变量。这些类是静态还是静态方法?周围的代码肯定会帮助你得到一个非常可靠的答案。 –