C#:DataTable 只获取一行搜索结果

C#: DataTable getting only one row of the search result

我在使用 DataTable 时遇到了一个突然而奇怪的问题。我正在使用带有 MySQL 数据库的 C# 来开发系统,并且正在尝试导出自定义报告。问题是,不知何故,我的 DataTable 只得到一个结果(我已经在 MySQL 上测试了我的查询,在 xls 文件和 DataTable 上应该有 30 个结果) . 奇怪的是,这些功能在系统的其他部分用于导出其他类型的报告,并且完美运行。这是我正在使用的 select 函数:

public DataTable selectBD(String tabela, String colunas) {
    var query = "SELECT " + colunas + " FROM " + tabela;
    var dt = new DataTable();

    Console.WriteLine("\n\n" + query + "\n\n");

    try
    {
        using (var command = new MySqlCommand(query, bdConn)) {
            MySqlDataReader reader = command.ExecuteReader();
            dt.Load(reader);
            reader.Close();
        }
    }
    catch (MySqlException) {
        return null;
    }
    bdConn.Close();

    return dt;
}

这是我的查询:

SELECT 
    cpf_cnpj, nomeCliente, agenciaContrato, contaContrato, 
    regionalContrato, carteiraContrato, contratoContrato, 
    gcpjContrato, avalistaContrato, enderecoContrato, 
    telefoneContrato, dataChegadaContrato, dataFatoGerContrato,
    dataPrimeiraParcelaContrato, dataEmissaoContrato, valorPlanilhaDebitoContrato 
FROM 
    precadastro 
    INNER JOIN 
    contrato 
        ON precadastro.cpf_cnpj = contrato.FK_cpf_cnpj 
    LEFT JOIN faseprocessual 
        ON contrato.idContrato = faseprocessual.FK_idContrato

那就是 result of the query on SQLyog

我测试过,函数返回的DataTable只收到一行,并不是MySQL结果的第一行。以前有人遇到过这种问题吗?

DataTable 加载需要来自您的数据的主键(由 DataReader 提供)并尝试从传递的行中猜测它。由于没有这样的键,Load 方法猜测它是第一列 (cpf_cnpj)。但是,该列中的值不是唯一的,因此每一行都会被下一行覆盖,结果只是 DataTable 中的一行。 这是多年来一直存在的问题,我不确定是否有一种解决方案可以解决所有问题。 :)

你可以试试:

  • 更改查询,使一些唯一值进入第一列(不幸的是,我在你的屏幕截图中看不到任何独特的东西)或连接两个或更多值以获得唯一值。
  • 自己准备DataTable创建列(这个结果集的镜像结构)然后遍历DataReader复制数据
  • 在您的查询中添加一些自动增量值(或使用 auto_increment 列创建临时 table 然后填充 table)

最后的建议可能是这样的(我对 mySql 的工作不多,所以这是我用 google 搜索的一些建议 :)):

SELECT 
    @i:=@i+1 AS id,
    cpf_cnpj, nomeCliente, agenciaContrato, contaContrato, 
    regionalContrato, carteiraContrato, contratoContrato, 
    gcpjContrato, avalistaContrato, enderecoContrato, 
    telefoneContrato, dataChegadaContrato, dataFatoGerContrato,
    dataPrimeiraParcelaContrato, dataEmissaoContrato, valorPlanilhaDebitoContrato 
FROM 
    precadastro 
    INNER JOIN 
    contrato 
        ON precadastro.cpf_cnpj = contrato.FK_cpf_cnpj 
    LEFT JOIN faseprocessual 
        ON contrato.idContrato = faseprocessual.FK_idContrato
    CROSS JOIN (SELECT @i:= 0) AS i

这里是answer on SO,它在查询中使用了自动编号。