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

基になる接続を暗黙的に閉じるDataReaderfrom 内で 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

using (var conn = connectLocal())

接続を using ステートメント内に配置しているため、次の行に到達した後に接続を閉じて破棄します。

return reader;

つまり、呼び出し元が応答をreader返すと、データベース接続が閉じられ、行をフェッチできなくなります。行が読み取られている間、接続が開いている必要があります。

于 2012-07-09T21:01:55.513 に答える
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 に答える
0

リーダーを使用する前に接続を破棄しているように見えます。リーダーの使用が終了した後でのみ、接続を破棄してみてください。

于 2012-07-09T21:00:35.507 に答える