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

时间:2014-03-26 14:15:26

标签: c# datatable firebird

这里有一个密切相关的问题:.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“将”结果放在第一位?

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

3 个答案:

答案 0 :(得分:4)

即使我不知道问题,我建议改用DataAdapter。也许这有效:

// Get the results
using(var da = new FbDataAdapter(sqlCmd))
{
    // Load the results into the table
    da.Fill(result);
}

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

答案 1 :(得分:3)

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

DataTable.Load这是一个非常古老的问题,并没有很好的记录。一般情况SQLDataAdapter适用于DataTable

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

答案 2 :(得分:1)

问题的灵魂如下:

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

但是,对于使用主键的列使用不同的别名确实可以解决问题,所有结果都会加载到DataTable中,因为看起来此列的信息是使用别名覆盖主键