DataTable.Load 显示的行数少于源 DataReader

Posted

技术标签:

【中文标题】DataTable.Load 显示的行数少于源 DataReader【英文标题】:DataTable.Load shows less rows than source DataReader 【发布时间】:2015-04-24 22:19:16 【问题描述】:

我刚刚注意到我的 ASP.NET 应用程序在 mysql 和 SQL Server 上运行时出现了一个奇怪的行为。

应用程序通过 EF 连接发出纯 SQL 查询以构建数据集。结果集不包含任何主代理键(主键不是SELECT 语句的一部分)。查询非常复杂,我不能展示它们,但我可以非常清楚地解释会发生什么。

给定查询

select a.A01, a.A01a, a.A01b, a.A02, a.A03, A11, A12, A12a, A12b, A12c, A21, A22, A23, A24, A25, A31, A31a, A31b, A32, A33, A33a, A33b, A33c, A34, A41, A42, A43, A51, A52, A53, A54, A54a, A54b, A54c, B11, B12, B13, B14, B15, Z0, a.prog, a.utente, C11, D11, D13, D14, D14a, D14b, D14c, D15, D16, D17, D18, D19, D21, D22, D23, D31, D32, D41, D42, D43, D44, D45, Z1
FROM TABLE_A JOIN TABLE_B
WHERE SOME_CONDITION
ORDER BY a.a21 ASC, a.a03 ASC LIMIT 20000

以下代码片段发出查询:

    protected DataTable GetDataTableV1(string aSqlStatement)
    
        DataTable dtResult = new DataTable();

        using (DbContext dataContext = GetDataContext())
        
            using (IDbConnection connection = dataContext.Database.Connection)
            
                connection.Open();
                using (IDbCommand command = connection.CreateCommand())
                
                    command.CommandText = aSqlStatement;
                    using (IDataReader reader = command.ExecuteReader())
                    
                        dtResult.Load(reader);
                    
                
            
        
        return dtResult;
    

在 Workbench 和 SMSS 中运行的查询在我的情况下返回 1192 个结果。没事儿。但是当应用在 MYSQL 上运行时,我只得到 1156 个结果!

如果我调试到在 MySQL 上运行的 dtResult.Load(reader);,我会得到一个意想不到的行为(并且仅在 MySQL 上):阅读器由 1192 个结果组成。

显然,从调试中读取 DataReader 会消耗它,所以我可以再次调试它。 现在它显示了 1156 条记录!

感谢代码中的“导出到 CSV”功能,我检查了结果数据集。还记得查询是按字段A21A03 升序排列的吗?看起来虽然这些字段不是主键、唯一、不同或其他的一部分,但 DataTable 会删除具有匹配对的行。

我的意思是,在分析结果数据集时,MS SQL 数据集中存在但 MySQL 数据集中缺失的每一行都显示了完全相同的一对下面截图的第 1 列和第 3 列作为下一个。在我的示例中,这些列分别是 CN。而且,同样,这些列不是主键的一部分

我的问题是

为什么 DataTable 在 MySQL 上的行为only如此?如何在我的 DataTable 中包含完整的结果集?

【问题讨论】:

您确定这与以下内容无关吗? -ORDER BY a.a21 ASC, a.a03 ASC LIMIT 20000 不确定查询是否在 2 个不同的 DBMS 中处理相同,您是否尝试过选择 Top 1192 记录,如果LIMIT 适用于 My Sql 而不是 Sql Server.. 或者反之亦然... 发现了一个骗子:***.com/questions/229425/… 对不起,我没有解释清楚。该应用程序将查询转换为正确的 LIMIT 格式。也就是说,如果它在 SQL 上运行,它会在选择后放置一个 TOP 20000,而不是在 Mysql 上它会在最后放置一个 LIMIT 20000。 WHERE 条件未修改 好的,感谢您的澄清.. using (IDataReader 用于此行使用 DataReader instead of IDataReader 我有兴趣看到它是否有效,然后我想我知道问题所在.. 它通常可以工作,因为 MysqlDataReader 继承了实现 IDataReader 的 DataReader。实际上这些接口在 ADO API 中很少使用 【参考方案1】:

解决方案是将整个查询包装在 SELECT 语句中,正如 here 所述

【讨论】:

以上是关于DataTable.Load 显示的行数少于源 DataReader的主要内容,如果未能解决你的问题,请参考以下文章

dplyr transmute 返回的行数少于原始数据帧

插入大查询表的行数少于预期

查询在 JDBC 中使用时返回的行数少于 SQL 开发人员

根据 div 中的行数显示“阅读更多”按钮

如何在记事本++中删除一行中少于11个但多于8个数字的行

窗口函数