1

我正在我的应用程序中实现一个数据库管理器类,主要是因为有 3 个数据库要连接到一个本地数据库。

但是返回函数不起作用,我知道查询带回了行,但是当它被类返回时它有 0。我错过了什么?

public MySqlDataReader localfetchrows(string query, List<MySqlParameter> dbparams = null)
    {
        using (var conn = connectLocal())
        {
            Console.WriteLine("Connecting local : " + conn.ServerVersion);
            MySqlCommand sql = conn.CreateCommand();
            sql.CommandText = query;
            if (dbparams != null)
            {
                if (dbparams.Count > 0)
                {
                    sql.Parameters.AddRange(dbparams.ToArray());
                }
            }
            MySqlDataReader reader = sql.ExecuteReader();
            Console.WriteLine("Reading data : " + reader.HasRows + reader.FieldCount);
            return reader;
            /*
            using (MySqlCommand sql = conn.CreateCommand())
            {
                sql.CommandText = query;
                if (dbparams != null)
                {
                    if (dbparams.Count > 0)
                    {
                        sql.Parameters.AddRange(dbparams.ToArray());
                    }
                }

                MySqlDataReader reader = sql.ExecuteReader();
                Console.WriteLine("Reading data : " + reader.HasRows + reader.FieldCount);

                sql.Parameters.Clear();
                return reader;
            }*/
        }

    }

以及获取结果的代码

query = @"SELECT jobtypeid, title FROM jobtypes WHERE active = 'Y' ORDER BY title ASC";
            //parentfrm.jobtypes = db.localfetchrows(query);
            var rows = db.localfetchrows(query);
            Console.WriteLine("Reading data : " + rows.HasRows + rows.FieldCount);
            while (rows.Read()){

            }

这些脚本返回以下内容:

Connecting local : 5.5.16
Reading data : True2
Reading data : False0
4

4 回答 4

2

您想DataReader从 a中返回 a ,using-statement这将隐式关闭底层连接。

而不是返回DataReader我会推荐以下模式。你可以让步IEnumerable<IDatarecord>

public IEnumerable<IDataRecord> localfetchrows(string query, List<MySqlParameter> dbparams = null)
{
    using (var conn = connectLocal())
    {
        MySqlCommand sql = conn.CreateCommand();
        sql.CommandText = query;
        if (dbparams != null)
        {
            if (dbparams.Count > 0)
            {
                sql.Parameters.AddRange(dbparams.ToArray());
            }
        }

        conn.Open();
        using (IDataReader rdr = sql.ExecuteReader())
        {
            while (rdr.Read())
            {
                yield return (IDataRecord)rdr;
            }
        }
    }
}

例如,您可以通过以下方式调用它:

var records = localfetchrows(query);
foreach (var rec in records.Take(10))
{ 
     Console.WriteLine("Reading data : " + rec.FieldCount);
}

因此,您无需将所有内容都加载到内存中,只是为了获取其中的一小部分。

于 2012-07-09T20:56:01.983 回答
1

您使用块在 MySqlConnection 内创建阅读器,当您从该块退出时,您的阅读器没有可使用的连接。

一种可能但效率较低的解决方案是使用 Fill 方法取回数据集。这不仅效率较低,而且,如果您需要处理数据行,您会发现自己在行上再次循环

public DataSet localfetchrows(string query, List<MySqlParameter> dbparams = null) 
{ 
    DataSet ds;
    using (var conn = connectLocal()) 
    { 
        Console.WriteLine("Connecting local : " + conn.ServerVersion); 
        MySqlCommand sql = conn.CreateCommand(); 
        sql.CommandText = query; 
        if (dbparams != null) 
        { 
            if (dbparams.Count > 0) 
            { 
                sql.Parameters.AddRange(dbparams.ToArray()); 
            } 
        } 
        MySqlDataReader reader = sql.ExecuteReader(); 
        Console.WriteLine("Reading data : " + reader.HasRows + reader.FieldCount); 
        reader.Fill(ds);
        return ds; 
    }
}
于 2012-07-09T21:01:29.643 回答
1

using (var conn = connectLocal())

您将连接放在 using 语句中,因此在到达此行后关闭并处理连接:

return reader;

换句话说,当调用者得到reader回复时,您已经关闭了数据库连接并且无法获取行。读取行时必须打开连接。

于 2012-07-09T21:01:55.513 回答
0

在我看来,您在使用阅读器之前正在处理连接。仅在阅读器完成后尝试处理连接。

于 2012-07-09T21:00:35.507 回答