【问题标题】:DataTable.Load(FbDataReader) does not load everything into DataTableDataTable.Load(FbDataReader) 不会将所有内容加载到 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有关还是与查询有关。

标签: c# datatable firebird


【解决方案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:这是一个类似的问题:stackoverflow.com/questions/229425/…
    • 谢谢,我想我现在知道会发生什么了。我将编辑我的问题以包含我的想法。
    【解决方案3】:

    问题的思路如下:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-17
      • 1970-01-01
      • 2018-11-21
      • 2012-03-31
      • 1970-01-01
      • 2021-08-14
      相关资源
      最近更新 更多