11

アクセスデータベースからデータを取得する方法について少し混乱しています。最初にリストに収集してからリストからそれらのデータを取得するのが適切ですか、それともデータベースに直接取得しても問題ありませんか?

私のコードは完全に正常に機能しますが、これを行うためのより良い方法があるかどうか知りたいですか?:

 private void button3_Click(object sender, EventArgs e)
    {
        OleDbConnection connection = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\redgabanan\Desktop\Gabanan_Red_dbaseCon\Red_Database.accdb");
        connection.Open();
        OleDbDataReader reader = null;
        OleDbCommand command = new OleDbCommand("SELECT * from  Users WHERE LastName='"+textBox8.Text+"'", connection);
        reader = command.ExecuteReader();
        listBox1.Items.Clear();

        while (reader.Read())
        {

            listBox1.Items.Add(reader[1].ToString()+","+reader[2].ToString());
        }

        connection.Close();

*データベースから直接レコードを取得し、リストボックスに表示しています。

4

4 に答える 4

21

親指のように突き出ているのは、SQLInjectionであり、パラメータ化されたクエリを使用することです。例:

OleDbCommand command = new OleDbCommand("SELECT * from  Users WHERE LastName='@1'", connection);
        
command.Parameters.AddWithValue("@1", textBox8.Text)

一般的にはSQLデータベースを使用する方が良いでしょうが、あなたがしていることは完全に受け入れられます。

編集:GUIからビジネスロジックを分離する方法は次のとおりです。

Class BusLogic
{
 public List<string> ListboxItems = new List<string>();
 public void PopulateListBoxItems(string userName)
 {
  string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\redgabanan\Desktop\Gabanan_Red_dbaseCon\Red_Database.accdb";
  using (OleDbConnection connection = new OleDbConnection(connString))
  {
        connection.Open();
        OleDbDataReader reader = null;
        OleDbCommand command = new OleDbCommand("SELECT * from  Users WHERE LastName='@1'", connection);            
        command.Parameters.AddWithValue("@1", userName)
        reader = command.ExecuteReader();    
        while (reader.Read())
        {
            ListboxItems.Add(reader[1].ToString()+","+reader[2].ToString());
        }    
   }
 }    
}

GUI

private void button3_Click(object sender, EventArgs e)
{        
      var busLogic = new BusLogic();
      busLogic.PopulateListBoxItems(textBox8.Text);          
      \\listBox1.Items.Clear();
      ListboxItems.DataSource = busLogic.ListboxItems;
}

この「MVC」アプローチの利点は、Bindingを使用してバインドされているコントロールに依存している場合にのみ、BusLogicをテストする必要があることです。

ps理想的ListboxItemsには、呼び出し元からの追加/削除などの機能を公開しないように、ListではなくIEnumerableになります。これは優れたAPI設計です。

于 2013-03-01T01:02:43.277 に答える
4

答えは両方とも「はい」だと思います。

あなたが今していることは、単純な場合には完全に受け入れられます。「スケーリング」がうまくいかないことに注意してください。つまり、10個または20個のアイテムをロードしても問題ありません。しかし、それが1万または100万になるとどうなりますか?

その場合、Model-View-Controller(MVC)アーキテクチャーの使用を検討します。それ自体はトピックですが、基本的にはリストボックス(「ビュー」)をデータ(「モデル」)から切り離します。

C#中心のMVCディスカッションについては、このサイトを参照してください

現在行っていることと本格的なMVCアーキテクチャの間に、提案どおりに実行したい場合があります。最初にリストをロードしてから、リストボックスに追加します。一度だけロードしても何も得られませんが、リストが「あちこちに」ロードされている場合は、一度アクセスするだけでデータベースIOのオーバーヘッドを毎回節約できます。

あなたが質問をしようと思ったという事実は、あなたが正しい軌道に乗っていることを示しています。

于 2013-03-01T01:05:49.903 に答える
2

コードは問題なく動作しますが、両方とが。をスローする可能性があるため、この例のようにいくつかの例外処理を実行することをお勧めします。OleDbConnection.Open()OleDbCommand.ExecuteReader()InvalidOperationException

using接続をステートメントでラップすることも一般的であるため、最終的connection.close()には自動的に呼び出されますが、これは個人的な好みにすぎません。

于 2013-03-01T01:10:04.560 に答える
1

データアクセス関数を異なるクラスに分けたり、レコードを取得するためのジェネリック関数を作成したりできます。

于 2013-03-01T00:59:58.963 に答える