调用“多个”的正确方式是什么;SQL数据读取器“;C#中的s?

调用“多个”的正确方式是什么;SQL数据读取器“;C#中的s?,c#,sql,database,linq,C#,Sql,Database,Linq,我调用ExecuteReader()获取数据,然后我需要通过另一个查询获取另一个数据。我的结构一直是这样的: class SomeClass { public static void Main(String[] args) { SqlConnection sqlConn = new SqlConnection(); sqlConn.ConnectionString = "some connection string" SqlCo

我调用ExecuteReader()获取数据,然后我需要通过另一个查询获取另一个数据。我的结构一直是这样的:

class SomeClass
{
    public static void Main(String[] args)
    {
        SqlConnection sqlConn = new SqlConnection();
        sqlConn.ConnectionString = "some connection string" 

        SqlCommand SQLCmd = new SqlCommand();
        SQLCmd.CommandText = "some query";
        SQLCmd.Connection = sqlConn;
        sqlConn.Open();

        sqlReader = SQLCmd.ExecuteReader();

        while (sqlReader.Read())
        {
            //some stuff here
        }

        sqlReader.Dispose();
        sqlReader.Close();
        sqlConn.Close();

        SQLCmd.CommandText = "another query";
        sqlConn.Open();
        sqlReader = SQLCmd.ExecuteReader();

        while (sqlReader.Read())
        {
            //some other stuff here
        }

        sqlReader.Dispose();
        sqlReader.Close();
        sqlConn.Close();
    }
}
它们共享相同的连接字符串。他们还能分享什么?它们能否共享相同的
sqlConn.Open()?资源分配和避免错误的正确方法是什么


顺便说一句,它按原样工作。提前感谢。

使用“使用”,您无需手动关闭和处置

using (SqlConnection connection = new SqlConnection(connectionString)) 
{    
     connection.Open();
     SqlCommand command = new SqlCommand("spTest", connection);
     command.CommandType = CommandType.StoredProcedure;
     command.Parameters.Add(new SqlParameter("@employeeid", employeeID));
     command.CommandTimeout = 5;

     command.ExecuteNonQuery();
}

正确的方法是使用
-语句将
SqlConnection
s和
SqlCommand
s包装在
中。这将强制在离开using块时对对象调用
Dispose
,即使抛出异常也是如此。(您当前的代码并非如此。)

符合

using(var cnn = new SqlConnection("connectionstring")){
    cnn.Open();
    using(var cmd = new SqlCommand("SELECT 1")){
       var reader = cmd.ExecuteReader();
       while(reader.Read()) { /* doStuff */ }
    }
}

无论采用何种方法,
Close
/
Dispose
实际上都不会关闭连接,因为连接设置非常昂贵。它只会将连接返回到连接池,并允许其他命令/读卡器使用它。

这就是我编写所有这些内容的方式:

class SomeClass
{
 public static void Main(String[] args)
 {
  using (SqlConnection sqlConn = new SqlConnection("some connection string"))
  {
   sqlConn.Open();

   using (SqlCommand comm = new SqlCommand("some query", conn))
   using (var sqlReader = comm.ExecuteReader())
   {
    while (sqlReader.Read())
    {
     //some stuff here
    }
   }

   using (SqlCommand comm = new SqlCommand("some query", conn))
   using (var sqlReader = comm.ExecuteReader())
   {
    while (sqlReader.Read())
    {
     //some other stuff here
    }
   }
  }
 }
}
using
语句处理块完成时的项目处理。至于共享内容,您可以让跨命令的连接保持打开状态

最重要的是要处理掉所有这些连接,但我倾向于尊重
使用
语句,如果一个项是
IDisposable
,而不管它在后台实际做了什么(这可能会因为它是一个实现细节而改变)

不要忘记,一个命令和一个读卡器中还有多个活动结果集,您可以将读卡器前进到下一个结果集。
对于如何写这一切,我略显轻率的回答是:

 return connection.Query<T>(procedureName, param, commandType: CommandType.StoredProcedure);
返回connection.Query(procedureName,param,commandType:commandType.StoredProcedure);

使用简洁;-)

正如我在评论中提到的-如果可能,将两个查询合并为一个查询,然后(如果它仍然生成多个结果集),使用继续

偷了亚当的,但换了钱:

class SomeClass
{
 public static void Main(String[] args)
 {
  using (SqlConnection sqlConn = new SqlConnection("some connection string"))
  {
   sqlConn.Open();

   using (SqlCommand comm = new SqlCommand("some query; some other query;", conn))
   using (var sqlReader = comm.ExecuteReader())
   {
    while (sqlReader.Read())
    {
     //some stuff here
    }
    if(sqlReader.NextResult())
    {
      while (sqlReader.Read())
      {
       //some other stuff here
      }
     }
    }
  }
 }
}

每次需要时都打开一个新连接,这是一种最佳做法。net使用连接池来管理连接。

要管理资源,您可以使用
使用
如下所示
... 

只能对实现了
IDispose
接口的类使用
using

在您的示例中,您可以将
SqlConnection
SqlCommand
与使用代码块一起使用。

但不要忘记try-catch语句:)


请记住使用
using
如果可能,将两个查询合并为一个查询,如果仍然生成两个结果集,则使用来处理这两个结果集。
sqlConn.Open()
只需打开
SqlConnection
。如果两个
SqlDataReader
使用相同的连接,那么它们也可以使用
sqlConn.Open()
。相关:@EmreAcar奇怪的是,你的代码与解释使用MARS从一个阅读器读取两组数据的代码非常相似。@Adamhuldsworth可能是我读过的学习C的书的作者,从这些帖子中复制了一些例子,因为我一直使用这些变量名:)没有回答以下问题:“调用多个”SQL数据读取器的正确方法是什么?".重要的是,他不能在第一个循环中使用第二个
数据读取器
。因此,如果他需要,最好先填写一个
列表
,他可以从第二个循环中访问该列表。@TimSchmelter哦,我明白了,以防他打算在第二个循环中从前一个读取器获取内容或其他什么?是的,没有发现这一点。+1感谢你费心去写它,即使是偷窃;-)为了完整性,我把你的答案和我的答案联系起来。@Adamhuldsworth-我也是你的+1(如果答案中没有这一点和明确的信用,我不会偷窃)@AdamHouldsworth感谢你们两位今天帮助我学习新知识。我必须同意Damien的回答,但如果可以,我会同意你们两位。@EmreAcar没问题,很高兴我们能帮忙:-)
 SQLCmd.CommandText = "some query";
 SQLCmd.Connection = sqlConn;
 sqlConn.Open();

//using will dispose reader automatically.
 using(sqlReader = SQLCmd.ExecuteReader())
{
   while (sqlReader.Read())
    {
    //some stuff here
    }
}
 //sqlReader.Dispose();
 //sqlReader.Close();
 //sqlConn.Close();

 SQLCmd.CommandText = "another query";
//no need to open connection again.
// sqlConn.Open();
// sqlReader = SQLCmd.ExecuteReader();

 using(sqlReader = SQLCmd.ExecuteReader())
{
   while (sqlReader.Read())
    {
    //some stuff here
    }
}
 //sqlReader.Dispose();
 //sqlReader.Close();
 //sqlConn.Close();
class SomeClass
{
 public static void Main(String[] args)
 {
  using (SqlConnection sqlConn = new SqlConnection("some connection string"))
  {
   try{
   sqlConn.Open();

   using (SqlCommand comm = new SqlCommand("some query", conn))
   using (var sqlReader = comm.ExecuteReader())
   {
    while (sqlReader.Read())
    {
     //some stuff here
    }
   }

   using (SqlCommand comm = new SqlCommand("some query", conn))
   using (var sqlReader = comm.ExecuteReader())
   {
    while (sqlReader.Read())
    {
     //some other stuff here
    }
   }
   }
   catch()
{
// Do exception catching here or rollbacktransaction if your using begin transact
}
finally
{
sqlConn.Close();
}
  }
 }
}