为什么mysql在用于ef时抛出datareader异常

2q5ifsrm  于 2021-06-25  发布在  Mysql
关注(0)|答案(1)|浏览(362)

我一直在尝试使用实体框架6的mysql。我有几个项目是成功地使用SQLServerExpress没有问题。新的项目是基于这些以前的项目,我需要一些小的变化,以连接和种子ef数据库。我现在遇到的问题是,在SQLServer上运行良好的简单查询在使用mysql时引发异常。
涉及两个表/实体。 Device 是收集数据样本的物理设备的表示。 Monitor 是要采样的数据类型的定义。因此,为每个设备定义了多个监视器。当我尝试检索设备的监视器列表时,它会抛出以下错误:

MySql.Data.MySqlClient.MySqlException: There is already an open DataReader associated with this Connection which must be closed first.

代码如下:

using (var context = new ApplicationDbContext())
{
    foreach (var device in context.Devices)
    {
        var monitors = device.Monitors.Where(m => m.Enabled == true).ToList();

        if (monitors.Count > 0)
        {
            // Get sampled data from device
        }
    }
}

我猜这是mysql驱动程序在ef实现方面的问题。有人知道如何纠正或解决这个问题吗?我做的事情真的很愚蠢很明显,我只是没有看到?在sqlserver实现中,我一直使用这些相同的模式来访问相关的实体。所以,我担心这将成为使用mysql的一个障碍,至少对其内置驱动程序来说是这样。
一些相关信息:
.net:4.5.2版
环境足迹:6
mysql:5.7版本
mysqlclient:6.9.11.0

u4vypkhs

u4vypkhs1#

这是因为 context.Devices 是保持 MySqlDataReader 打开(懒散地流式传输结果),但是 device.Monitors.Where(...) 尝试在同一连接上执行第二个查询。
我可以想出两个解决办法:

1. 强制计算第一个查询

使用 .ToList() 要强制将所有结果存入内存:

foreach (var device in context.Devices.ToList())

请注意,这是不必要的低效,因为它可能会将大量可能不需要的数据带回内存。

2. 将两个查询合并为一个查询

foreach (var device in context.Devices.Where(d => d.Monitors.Any(m => m.Enabled)))
{
    // Get sampled data from device
}

这将导致ef构造一个只检索 device 对象,并避免“已打开datareader”错误。

相关问题