2009-09-01 25 views
4

当使用像这样的结构时,我可以避免打开的DataReader异常(“已经有一个与此命令关联的打开的DataReader,它必须先关闭”)?使用嵌套命令时可以避免打开的DataReader异常吗?

public void FirstMethod() 
{ 
    using (var command = connection.CreateCommand()) 
    { 
     command.CommandText = "..."; 
     using (var reader = command.ExecuteReader()) 
     { 
      // do something with the data 
      SecondMethod(); 
     } 
    } 
} 

public void SecondMethod() 
{ 
    using (var command = connection.CreateCommand()) 
    { 
     command.CommandText = "..."; 
     using (var reader = command.ExecuteReader()) // Exception 
     { 
     } 
    } 
} 

此致

回答

3

你可以使用本地连接(即本地的方法);通过连接池,将连接保持为一个领域的优势是最小的,并且经常导致这种类型的...乐趣。当然,如果您正在编辑数据,则可能会遇到阻止自己的问题 - 可能使用诸如TransactionScope之类的方法进行缓解。示例在底部...

或者,您可以在连接上启用MARS(多个活动结果集)应该这样做。只需在连接字符串(SQL Server 2005及更高版本)中包含“MultipleActiveResultSets = True”即可。

public void FirstMethod() { 
    using (var connection = CreateAndOpenConnection()) 
    using (var command = connection.CreateCommand()) { 
     command.CommandText = "..."; 
     using (var reader = command.ExecuteReader()) { 
      // do something with the data 
      SecondMethod(); 
     } 
    } 
} 
public void SecondMethod() { 
    using (var connection = CreateAndOpenConnection()) 
    using (var command = connection.CreateCommand()) { 
     command.CommandText = "..."; 
     using (var reader = command.ExecuteReader()) // Exception 
     { } 
    } 
} 
private SqlConnection CreateAndOpenConnection() { 
    var conn = new SqlConnection(connectionString); 
    conn.Open(); // perhaps dispose if this fails... 
    return conn; 
} 
-2

你为什么不改变你的方法签名?

public void FirstMethod() 
{ 
    using (var command = connection.CreateCommand()) 
    { 
     command.CommandText = "..."; 
     using (var reader = command.ExecuteReader()) 
     { 
      // do something with the data 
      SecondMethod(reader); 
     } 
    } 
} 

public void SecondMethod(var reader) 
{ 
    // do stuff with reader... 
} 

这不仅避免了问题,但它也导致更少的开销,你只创建1 command/reader而不是2(这里假设你的方法调用是同步的。)

另外,请考虑使用强类型变量而不是var关键字;引入了var以支持匿名类型,只有在必要时才应使用。

+1

那么我会这样做,如果第二种方法将基于相同的SQL语句,这当然不是这种情况(否则,为什么我需要的方法?)。 – 2009-09-01 12:01:25

+0

@Ian:所有变量在C#中都是强类型的,但是你声明它们。 (C#4,当它被释放时,将允许使用'动态'变量,但它们与'var'关键字无关。) – LukeH 2009-09-01 12:13:00

+0

是的,var关键字只是隐藏了具体类型,但隐含地表示它。所以你可以写“int i = 1”以及“var i = 1”,两个语句都是相等的。 – 2009-09-01 12:24:54