3
SqlDataReader myreader = null;
    SqlConnection sqlConn = null;

     cmbCat.Items.Clear();
    sqlConn = new SqlConnection("Data Source=tin;Initial Catalog=sample;Trusted_Connection=yes;");
    sqlConn.Open();
    SqlCommand sqlComm = new SqlCommand("SELECT members FROM  dbo.tbl_Category", sqlConn);

    myreader = sqlComm.ExecuteReader();
    if (myreader != null)
    {
        while (myreader.Read())
        {

            cmbCat.Items.Add(myreader["members"]);

        }
    }

    {
        if (myreader != null)
            myreader.Close();
        if (sqlConn != null)
        {
            if (sqlConn.State == ConnectionState.Open)
                sqlConn.Close();
        }
    }

データベースからコンボボックスにデータを取得する際に、次のコードがあります。データベースからコンボボックスにデータを入力する必要があるたびに、常にこのコードを配置します。私がやりたいことは、このコードを再構築してクラスに配置することです。コンボボックスにデータを入力する役割を担う関数を呼び出すだけです。しかし、私はそれを行う方法について混乱しています。私を助けてください。よろしくお願いします。良い一日を過ごしてください..

4

2 に答える 2

4

投稿したコードにはいくつかの懸念があります。簡略化されたコード セットを提供しようとしますが、この小さなコードのさまざまなニーズ (懸念事項) を分離すると、多くの異なるクラスが見つかりますが、余談になります。

まず、COPY-PASTE を使用してアプリケーション内のあらゆる場所に接続文字列を広げたくありません。これを処理する専用のクラスを作成する必要があります。

public class DatabaseGateway
{
  public IList<T> RetrieveSqlAs<T>(string queryString, ITransformer<SqlDataReader, T> rowTransformer)
  {
    var result = new List<T>();
    using (var sqlConn = new SqlConnection(connectionString))  // you can use a CONSTANT, or call to a .config file here
    using (var sqlCommand = new SqlCommand(queryString, sqlConn))
    {
      var myreader = sqlComm.ExecuteReader();
      while (myreader.Read())
      {
         result.Add(rowTransformer.Transform(myreader));
      }
    }
    return result;
  }
}

public class MemberRowTransformer : ITransformer<SqlDataReader, string>
{
  public string Transform(SqlDataReader from)
  {
    from["members"];  // handle null and anything else here
  }
}

public interface ITransformer<TFrom, TTo>
{
  TTo Transform(TFrom)
}

次に、次のように使用します。

var gateway = new DatabaseGateway();
var transformer = new MemberRowTransformer();

cmb.Items.Clear();
foreach (string i in gateway.RetrieveSqlAs("SELECT members FROM  dbo.tbl_Category", transformer))
{
  cmb.Items.Add(i);
}

これまで私と一緒だったなら、もう一歩進んでRepository Patternください。このクラスを追加します。

public class MembershipRepository
{
   public List<string> GetMembers()
   {
     var gateway = new DatabaseGateway();
     var transformer = new MemberRowTransformer();
     var result = new List<string>();

     foreach (string i in gateway.RetrieveSqlAs("SELECT members FROM  dbo.tbl_Category", transformer))
     {
       result.Add(i);
     }

     return result;
   }
}

次に、呼び出しコードは次のようになります。

var repository = new MembershipRepository();
cmb.Items.Clear();
foreach(string i in repository.GetMembers())
{
   cmb.Items.Add(i);
}

Generics、Repository Pattern、および Data Transfer Objects (DTO) のトピックを調べると、コードを複製する代わりに再利用できるクラスを作成する方法について、多くの優れたアイデアが見つかります。

注:簡単に単体テストと依存性注入を実行できるように、インターフェイスに分割するという全体的な演習は行っていません。これはより大きなトピックですが、同様に確認することをお勧めします。

于 2012-04-28T14:38:02.590 に答える
2

一般に、プレゼンテーション ロジックをビジネス/データ アクセス ロジックから分離しておく必要があります。DataTableそのため、データ アクセス コードは、または何らかのカスタム コレクションなどの一般的な形式でデータを返す必要があります。次に、フォームの呼び出しコードは、コンボボックスに入力する責任があります。

public List<string> GetCategories()
{
    List<string> cats = new List<string>();
    SqlDataReader myreader = null;
    ...
    while (myreader.Read())
        cats.Add((string)myreader["members"]);
    ...
    return cats;
}

次に、フォームで次のようにします。

protected void DoDataBinding()
{
    MyDataAccessClass dataAccess = new MyDataAccessClass();
    List<string> cats = dataAccess.GetCategories();
    cmb.Items.Clear();
    foreach (string cat in cats)
        cmb.Items.Add(cat);
}
于 2012-04-28T14:16:10.540 に答える