【问题标题】:MySqlDataReader returning only first rowMySqlDataReader 只返回第一行
【发布时间】:2021-11-18 20:49:49
【问题描述】:
public string GetAllProducts()
    {
        string connStr = "server=localhost;user=root;database=tp1;port=3306;password=";
        MySqlConnection conn = new MySqlConnection(connStr);
        try
        {
            Console.WriteLine("Connecting to MySQL...");
            conn.Open();

            string sql = "SELECT * FROM material";
            MySqlCommand cmd = new MySqlCommand(sql, conn);
            MySqlDataReader rdr = cmd.ExecuteReader();

            while (rdr.Read())
            {
                return (rdr[0] + " -- " + rdr[1] + " -- " + rdr[2] + " -- " + rdr[3]);
            }
            rdr.Close();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

        conn.Close();
        Console.WriteLine("Done.");


        return "No records found";
    }

此时我在“材料”表上有四个条目。只返回第一个。

这是输出:

SWAGGER OUTPUT

'material' content

【问题讨论】:

    标签: c# mysql-connector


    【解决方案1】:

    您已将return 放入读取数据的循环中。因此循环不会以循环方式执行!

    真的,你的代码应该看起来更像:

    public List<Product> GetAllProducts()
    {
        string connStr = "server=localhost;user=root;database=tp1;port=3306;password=";
    
        using var conn = new MySqlConnection(connStr);
        conn.Open();
    
        string sql = "SELECT * FROM material";
        using var cmd = new MySqlCommand(sql, conn);
        using var rdr = cmd.ExecuteReader();
        var products = new List<Product>();
        while (rdr.Read())
        {
             var p = new Product(
               rdr.GetInt32(0), //id
               rdr.GetString(1), //ref
               rdr.GetString(2), //name
               rdr.GetInt32(3) //qty
             );
             products.Add(p);
        }
        return products;
    }
    
    public record Product(int Id, string Ref, string Name, int Qty);
    

    (为清楚起见,删除了 try/catch;请随时将其放回)

    请注意,此 C# 使用更新的功能,例如记录和使用 var;如果您遇到语法错误,请告诉我它们是什么,以便我可以建议与您的 C# 版本兼容的不同语法


    顺便说一句,我发现这种从数据库中获取数据的方法非常乏味。您可以通过安装一个名为 Dapper 的库来大量减少它。使用 Dapper,我上面写的所有代码都简化为:

    public List<Product> GetAllProducts()
    {
        string connStr = "server=localhost;user=root;database=tp1;port=3306;password=";
    
        using var conn = new MySqlConnection(connStr);
        return conn.Query<Product>("SELECT * FROM material").ToList();
    }
    

    如果你想参数化你的查询:

    public List<Product> GetAllProductsNamed(string n)
    {
        string connStr = "server=localhost;user=root;database=tp1;port=3306;password=";
    
        using var conn = new MySqlConnection(connStr);
        return conn.Query<Product>(
          "SELECT * FROM material WHERE name = @theName", 
          new{ theName = n }
        ).ToList();
    }
    

    如果你不打算使用像 EF 这样的高性能 ORM,那么生命太短,不能使用 Dapper(无从属关系):)

    【讨论】:

    • 感谢您的回复。让它工作没有语法错误。由于我有一个名为 Product 的模型,我不能使用它吗?
    • 你当然可以..我只是在发布的代码中看不到一个,所以我做了一个记录(这样我也可以知道属性名称等/提供与自己一致的代码),因为使用record X(T Y, T Z) 语法可以快速轻松地敲出记录。删除代码的最后一行并将属性名称调整为您拥有的任何内容..
    • 查看关于 Dapper 的脚注
    【解决方案2】:

    您在第一个Read() 之后返回,试试这样:

    var output = string.Empty;
    
    while (rdr.Read())
    {
       output += (rdr[0] + " -- " + rdr[1] + " -- " + rdr[2] + " -- " + rdr[3]);
    }
    rdr.Close();
    
    return output;
    

    【讨论】:

    • 成功了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 2013-12-01
    • 2017-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多