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

Posted

技术标签:

【中文标题】C#:DataTable 只获取搜索结果的一行【英文标题】:C#: DataTable getting only one row of the search result 【发布时间】:2017-08-22 05:02:51 【问题描述】:

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

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结果的第一行。以前有人遇到过这种问题吗?

【问题讨论】:

你的连接字符串是什么? this: "Persist Security Info = False;Server = localhost;DataBase = absadvocacia;Uid = root;Pwd = '''';"但除了那个地方,与数据库的连接工作得很好。登录、插入、更新、删除……其实我在其他地方也用过同样的功能(导出用户监控报告),就可以了。 你试过 while (reader.Read()) 【参考方案1】:

DataTable load 期望您的数据中的主键(由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,它在查询中使用自动编号。

【讨论】:

感谢您的回答,对我帮助很大。我尝试添加“@i:=@i+1 AS id”和“(SELECT @i:= 0) AS i”,它适用于 MySQL 控制台和 SQLyog,但不适用于我的 C# 代码和 Visual Studio 查询编辑。我搜索了一下,发现这可能是因为它真的无法完成 - 似乎它被阻止以防止 SQL 注入。但是,所以我再次查看了我的数据库,并且我的表“contrato”的主键(在这种情况下将始终是唯一的),所以我在生成 .xls 文件时将其忽略并只工作美好的。非常感谢。

以上是关于C#:DataTable 只获取搜索结果的一行的主要内容,如果未能解决你的问题,请参考以下文章

Winforms C#:从远程计算机文件夹获取图像并加载到 DataTable 的列中

C# datatable 去掉为空列的行

jQuery Datatable:标题和搜索在同一行

关于c#中的datatable,不知道如何清空里面的数据

DataTable 从 C# 中的现有数据库结构自动填充

c# datatable 隐藏行?