2013-03-01 36 views
7

Tôi hơi bối rối về cách lấy dữ liệu từ cơ sở dữ liệu truy cập. Là nó thích hợp để thu thập nó đầu tiên trong một danh sách sau đó nhận được những dữ liệu từ danh sách của bạn hoặc nó là okay để chỉ cần trực tiếp có được nó trong cơ sở dữ liệu của bạn?Cách thích hợp để nhận dữ liệu từ Cơ sở dữ liệu Access

Mã của tôi hoạt động hoàn toàn tốt, nhưng tôi muốn biết liệu có cách nào tốt hơn để làm điều này không ?? :

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(); 

* Tôi nhận được hồ sơ của mình trực tiếp từ cơ sở dữ liệu, sau đó hiển thị hồ sơ đó trong hộp danh sách.

+0

Đem lại cho mình ngoại lệ chưa được xử lý. – kiran

Trả lời

15

Một điều đó là gắn bó ra như một ngón tay cái đau là SQL injection và sử dụng các truy vấn parameterised, ví dụ:

OleDbCommand command = new OleDbCommand("SELECT * from Users WHERE LastName='@1'", connection); 

command.Parameters.AddWithValue("@1", textBox8.Text) 

gì bạn đang làm là hoàn toàn chấp nhận được, mặc dù bạn nói chung sẽ được tốt hơn để sử dụng một lệnh SQL Cơ sở dữ liệu.

Edit: Đây là cách bạn tách logic kinh doanh của bạn từ 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; 
} 
+0

đúng, đó là rất dễ bị tổn thương với SQL injection, sử dụng tốt hơn các thông số AddwithValue :) – Pyromancer

+2

Cảm ơn. Đó là tất cả tôi muốn biết rằng mã của tôi là tốt. Tôi đã sử dụng truy vấn được Parametised ngay bây giờ. –

+0

Nếu bạn không có bất kỳ lỗi nào, điều đó tốt :) – Pyromancer

1

Bạn có thể tách các chức năng truy cập dữ liệu của mình trong các lớp khác nhau hoặc tạo các hàm chung để truy xuất bản ghi.

+0

vì vậy bạn có nghĩa là, công việc của tôi là okay? –

+0

+1 Cảm ơn vì điều này. Tôi đã bao gồm mã chứng minh điều này trong câu trả lời của tôi –

2

tôi sẽ nói câu trả lời là "có" cho cả hai.

Điều bạn đang làm bây giờ hoàn toàn có thể chấp nhận được đối với các trường hợp đơn giản. Chỉ cần lưu ý rằng nó không "quy mô" rất tốt. Nghĩa là, tải 10 hoặc 20 mục là tốt. Nhưng điều gì xảy ra nếu nó trở thành 10 nghìn hay một triệu?

Trong trường hợp đó, bạn muốn xem bằng cách sử dụng kiến ​​trúc Model-View-Controller (MVC). Đó là một chủ đề trong chính nó, nhưng về cơ bản bạn decouple listbox ("xem") từ dữ liệu ("mô hình").

Xem this site for a C#-centric MVC discussion

Trong giữa những gì bạn đang làm gì bây giờ và một kiến ​​trúc MVC toàn diện, bạn có thể chỉ đơn giản là muốn làm như bạn đề nghị - tải danh sách đầu tiên sau đó thêm chúng vào hộp danh sách. Điều đó giúp bạn không có gì nếu bạn chỉ tải nó một lần, nhưng nếu danh sách được tải "khắp nơi", bạn có thể lưu cơ sở dữ liệu IO trên mỗi lần bằng cách chỉ truy cập nó một lần.

Thực tế là bạn cho rằng đặt câu hỏi cho biết bạn đang đi đúng hướng.

+0

Thanks.Appreciated nhiều. –

2

Mặc dù mã của bạn hoạt động mà không có vấn đề gì, tôi khuyên bạn nên thực hiện một số xử lý ngoại lệ như trong this example, vì cả hai OleDbConnection.Open()OleDbCommand.ExecuteReader() có thể ném một InvalidOperationException.

Việc kết nối với tuyên bố using cũng phổ biến, vì vậy cuối cùng connection.close() được gọi tự động, nhưng đây chỉ là sở thích cá nhân.

+0

+1 Cảm ơn vì điều này. Tôi đã bao gồm mã trình bày điều này trong câu trả lời của tôi –

Các vấn đề liên quan