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

时间:2017-03-28 22:33:43

标签: c# mysql datatable datareader

DataTable我遇到了一个突然而奇怪的问题。我正在使用C#和MySQL数据库来开发系统,我正在尝试导出自定义报告。问题是,不知何故,我的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结果的第一行。有人之前有过这种问题吗?

1 个答案:

答案 0 :(得分:0)

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

您可以尝试:

  • 更改查询,以便某些唯一值进入第一列(遗憾的是,我无法在屏幕截图中看到一些独特的内容)或连接两个或多个值以获得唯一值。
  • 通过创建列(结果集的此镜像结构)自行准备DataTable,然后遍历DataReader以复制数据。
  • 在查询中添加一些自动增量值(或使用auto_increment列创建临时表,然后填充该表)

最后的建议可能是这样的(我对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在查询中使用自动编号。