错误:此命令已关联一个必须先关闭的打开的DataReader。

3
我正在使用一个 SQL 连接来访问数据库中的不同表。然而,代码返回了以下错误。
错误:"已经有一个与此命令相关联的打开的 DataReader 必须先关闭"
MyContext conn = new MyContext()

protected void ChangeName(int id)
{
    User user = conn.MyOtherTable.First(x => x.id == id);

    var elements = conn.MyTable.Where(x => x.id == id && x.name == name).OrderBy(x => x.id).OrderBy(x => x.name).
                    .Select(t => new { t.id, t.name, }).GroupBy(t => new { t.id, t.name, });

                foreach (var item in elements)
                {
                    foreach (var row in item)
                    {
                        for (int j = 1; j <= 5; j++)
                        {
                            if (row.name == "name")
                            {
                                user.name1 = row.name;
                                conn.SaveChanges();
                            }
                            if (row.name == "name2")
                            {
                                user.name2 = row.name;
                                conn.SaveChanges();
                            }
                         }
                     }
            }
 }
2个回答

6

LINQ(在与数据库交互时)通常是一个非缓存式的API。要实现您想要的功能,请执行以下操作之一:

  • 启用多活动结果集(MARS)
  • 首先缓冲数据

我更喜欢第二种选项;它只需要将 .ToList() 添加到您的第一行即可:

var elements = conn.MyTable.Where(x => x.id == id && x.name == name)
        .OrderBy(x => x.id).OrderBy(x => x.name).
        .Select(t => new { t.id, t.name, }).GroupBy(t => new { t.id, t.name, })
        .ToList();

现在,在这行代码运行后,我们知道所有数据已经在内存中,并且读取器已关闭;之前它仍然可以从读取器中获取行输入。

为了完整起见,在此讨论了启用MARS - 尽管这不是我的建议。


你能解释一下为什么LINQ默认是非缓冲的spooling API吗? - sgarg

0

我和你一样计算错误,但是我启用了多个活动结果集(MARS),最后我只是将IDataReader变量方法从close()更改为dispose(),然后问题就消失了


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接