繁体   English   中英

C#中的SQL嵌套查询和连接打开问题

[英]SQL Nested Queries in C# and Connection Open Problem

我有三个表,我的要求是使用每个表的父记录来获取它们的记录。

所以我有三个查询。 这是一个代码示例:

第一次查询

SQLConnection con = new SQLConnection("connectionstring");

SQLCommand cmd1 = new SQLCommand (1stQuery,con);
SQLDataReader rs1 = cmd1.DataReader();

while (rs1.Read()) {

// Making 2nd Query, 2nd Query is using 1st Query result

SQLCommand cmd2 = new SQLCommand(2ndQuery,con);
SQLDataReader rs2 = cmd2.DataReader();

while (rs2.Read()){

//Making 3rd Query using 2nd Query result
}
}

它给出了一个错误,即已经有一个打开的DataReader。 我不想关闭SQL连接并为每个查询打开它,因为这不利于性能。

我只想对所有查询使用一个SQL连接。

您不需要关闭连接。 问题(错误提示)是您没有在启动下一个DataReader之前关闭它。

就像Oded所说的那样,您遇到了“选择N + 1”的问题,但是为了得到这个答案,让我们忽略它。

最简单的方法是在开始读取下一个数据集之前,将整个第一个数据集读取到内存中:

var list1 = new List<Foo>();
using (var rdr1 = cmd1.ExecuteReader())
{
    list1.Add(...);
}

var list2 = new List<Bar>();
var cmd2 = ...;
foreach (var item in list1)
{
    // assign parameters to cmd2 from item

    using (var rdr2 = cmd2.ExecuteReader())
    {
        list2.Add(...);
    }
}

... 等等。

另一个选项是在连接上启用MARS ,这使您可以同时激活多个DataReader。 这几乎总是一个坏主意,所以让我们假装我从未建议过。

如果要嵌套对数据库的调用,则需要使用其他连接。

在这里,通过循环调用数据库有一个更严重的问题-也称为N + 1问题

我建议重写数据库和应用程序逻辑-在数据库中使用联接将单独的查询合并为一个并更改逻辑以使用结果。

我建议使用ExecuteDataSet 它将包含所有三个查询的结果。 移动,这些查询应在存储过程中执行。

否则,您将邀请Sql注入

SQL注入

将您的连接字符串的MultipleActiveResultsets属性设置为true,但是代码的性能很差。 尝试将查询包装在存储过程中以避免循环。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM