DataTable.Load(FbDataReader) 不会将所有内容加载到 DataTable

Posted

技术标签:

【中文标题】DataTable.Load(FbDataReader) 不会将所有内容加载到 DataTable【英文标题】:DataTable.Load(FbDataReader) does not load everything into DataTable 【发布时间】:2014-05-05 00:24:11 【问题描述】:

这里有一个密切相关的问题:.NET DataTable skips rows on Load(DataReader)

我有一个返回 169 个结果的 SQL 查询。结果如下所示:

CustomerID Customer Name TerminalID Creation Date
     1     First Customer   12345   2010-07-07
     1     First Customer   12346   2010-07-07
     1     First Customer   12347   2010-07-07
     2     Second Customer  23456   2011-04-18

这个结果是正确的。

我在一个 C# 程序中输入查询并像这样执行它:

public DataTable getDataTableFromSql(FbCommand command)

    // Create a new datatable
    DataTable result = new DataTable();

    // Set up the connection
    using (FbConnection con = new FbConnection(this.connectionString))
    
        // Open the connection
        con.Open();

        // Set up the select command
        FbCommand sqlCmd = command;
        // Add the connection to it
        sqlCmd.Connection = con;

        try
        
            // Get the results
            using (FbDataReader sqlReader = sqlCmd.ExecuteReader())
            
                // Load the results into the table
                result.Load(sqlReader);
            
        
        catch (Exception ex)
        
            Console.WriteLine(ex);
        
    

    // Return the table
    return result;

此代码经过测试,适用于许多不同的 SQL 查询。 但对于上述查询,DataTable 仅包含 39 个结果,如下所示:

CustomerID Customer Name TerminalID Creation Date
     1     First Customer   12347   2010-07-07
     2     Second Customer  23456   2011-04-18

我稍微摆弄了一下代码,这是我目前发现的:FbDataReader 正确地从数据库中获取结果。如果我只查询TerminalID,我最终会在DataTable 中得到169 个结果。如果我查询CustomerID,我会收到 39 个结果。

结论:result.Load(sqlReader) 行将CustomerID 的结果分组并丢弃所有其他结果,无论它们是否可以分组。

为什么会这样?如何将我的查询结果加载到DataTable 而不会由于不合逻辑的分组而“丢失”任何行?为什么DataTable首先“分组”了结果?

注意:我还尝试了所有三个可用于DataTablesLoadOptions,结果都相同:只有 39 个结果加载到 DataTable

【问题讨论】:

你试过用dataadapter填充吗? 什么意思 " 如果我​​只查询 TerminalID"?如果您查看DataTable 内容,您在哪里以及如何查询它? @TimSchmelter:这意味着我编辑了我的 SQL 查询,以便它只返回列 TerminalId。当我再次运行程序时,我在DataTable 中收到所有 169 个结果。 @waka:DataReader 返回多少条记录?您是否在循环中使用了int 变量(while(sqlReader.Read()count++;))来查看数据库返回 39 条还是 169 条记录?那么你至少会知道你的问题是与DataTable.Load有关还是与查询有关。 .NET DataTable skips rows on Load(DataReader)的可能重复 【参考方案1】:

DataTable.Load 方法需要基础数据中的主键列(即来自DataReader)。看起来您的过程没有任何主键列,或者如果您有一个,请在 sql 语句中使用order by,以便DataTable 能够接受它作为主键。

这是DataTable.Load 的一个非常古老的问题,并且没有很好的记录。一般SQLDataAdapterDataTable 比较好。

在您的情况下,我认为一旦 Load 找到重复项,它就会停止加载数据。我没有在任何地方得到这个记录,但看起来像这个问题。

【讨论】:

【参考方案2】:

即使我不知道问题所在,我也建议改用DataAdapter。也许可行:

// Get the results
using(var da = new FbDataAdapter(sqlCmd))

    // Load the results into the table
    da.Fill(result);


为什么会这样?我认为 this answer 在另一个问题中解释了它。

【讨论】:

我刚刚对此进行了测试,我在DataTable 中得到了 169 个结果,谢谢!我真的很想知道为什么DataTable.Load() 似乎“吞下了”一些结果...:/ @waka:这是一个类似的问题:***.com/questions/229425/… 谢谢,我想我现在知道会发生什么了。我将编辑我的问题以包含我的想法。【参考方案3】:

问题的思路如下:

DataTable.Load() 在结果中查找主键。如果它尝试加载到DataTable主键已经存在于该表中,它会用新结果覆盖该行。

但是,为具有 主键 的列使用不同的别名确实可以解决问题,所有结果都将加载到 DataTable,因为似乎该列是主键被别名覆盖。

【讨论】:

以上是关于DataTable.Load(FbDataReader) 不会将所有内容加载到 DataTable的主要内容,如果未能解决你的问题,请参考以下文章

映射如何通过 .NET 中的 DataReader 通过 Load() 将数据读取到 DataTable?

有人对 DataTable.Load(DataReader) 方法有任何意见吗?

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

.load(SqlDataReader) 后数据表为空

SqlDataReader 与 SqlDataAdapter:返回 DataTable 的性能哪个更好?

加载 DataTable 时使用默认列值以避免 Null