包含SQL连接的嵌入式循环



我有以下代码:

SqlConnection connection1, connection2;
SqlCommand command1, command2;
SqlDataReader reader1, reader2;
using (connection1 = new SqlConnection("connection string here"))
{
    using (command1 = new SqlCommand(@"SELECT * FROM [SERVER1].[DATABASE1].[TABLE1] WHERE COL1 = @COL1 AND COL2 = @COL2", connection1))
    {
        command1.Parameters.Add("@COL1", SqlDbType.VarChar, 255).Value = TextBox1.Text;
        command1.Parameters.Add("@COL2", SqlDbType.VarChar, 255).Value = TextBox2.Text;
        connection1.Open();
        using (reader1 = command1.ExecuteReader())
        {
            while (reader1.Read())
            {
                int COL3Index = reader1.GetOrdinal("COL3");
                Console.Write("### LOOP 1 ###");
                Console.Write(reader1.GetDouble(COL3Index));
                using (connection2 = new SqlConnection("same connection string here"))
                {
                    using (command2 = new SqlCommand(@"SELECT * FROM [SERVER1].[DATABASE1].[TABLE2] WHERE COL1 = @COL1", connection1))
                    {
                        command2.Parameters.Add("@COL1", SqlDbType.Float).Value = reader1.GetDouble(COL3Index);
                        connection2.Open();
                        using (reader2 = command2.ExecuteReader())
                        {
                            while (reader2.Read())
                            {
                                int COL2Index = reader2.GetOrdinal("COL2");
                                Console.Write("### LOOP 2 ###");
                                Console.Write(reader2.GetDouble(COL2Index));
                            }
                        }
                    }
                }
            }
        }
    }
}

基本上,我将需要这样做5次,即循环内循环内循环内循环内循环…

第一个循环自己工作,但第二个循环不起作用,并给出以下错误:

已经有一个与这个命令相关联的打开的数据读取器必须先关闭

on line:

using (reader2 = command2.ExecuteReader())

当我需要嵌入循环

时,我该如何让它工作呢?

这是Select N+1的定义,应该尽可能避免。我建议使用实体框架之类的东西,并急切地加载子值。

如果不可能避免,循环遍历整个reader1结果,赋值给一个本地集合,关闭reader1,然后遍历本地集合并基于本地值加载

如果对相同的数据库/连接字符串启用了MARS,则没有理由打开两次连接。这可以通过将"MultipleActiveResultSets=True"添加到连接字符串来实现。

此外,您可以使用DataAdapter将数据加载到DataSet/DataTable中,然后查询DataSet。但是,这假设您的表不是太大,您可以将它们加载到内存中,否则ORM将是更好的选择。

一个ORM解决方案,如LINQ-to-SQL或LINQ-to-Entities通过实体框架(如在Mike Cole的回答中提到的)可以真正帮助你在这里,所以你不需要担心编写这些查询和处理连接。相反,您只需依赖于DataContext来处理连接。

最新更新