2009-02-27 24 views
7

Đây là bài viết đầu tiên của tôi trên StackOverflow, vì vậy hãy nhẹ nhàng ...ADO.NET Thực tiễn tốt nhất cho kết nối và DataAdaptor Object Phạm vi

Tôi có một số câu hỏi liên quan đến phạm vi đối tượng cho ADO.NET.

Khi tôi kết nối với một cơ sở dữ liệu, tôi thường sử dụng mã như thế này:

OleDbConnection conn = new OleDbConnection("my_connection_string"); 
conn.Open(); 
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * from Employees", conn); 
OleDbCommandBuilder cb = new OleDbCommandBuilder(adapter); 
DataTable dt = new DataTable(); 
adapter.Fill(dt); 
conn.Close(); 
conn.Dispose(); 

Hãy nói rằng tôi ràng buộc DataTable dẫn đến một điều khiển lưới điện và cho phép người dùng của tôi để chỉnh sửa nội dung lưới. Bây giờ, khi người dùng của tôi nhấn một nút Save, tôi cần phải gọi mã này:

adapter.Update(dt); 

Dưới đây là những câu hỏi của tôi:

1) Tôi có cần phải giữ lại các đối tượng bộ chuyển đổi mà tôi tạo ra khi tôi ban đầu được nạp datatable, hoặc tôi có thể tạo một đối tượng adapter trong sự kiện bấm nút Save để thực hiện cập nhật?

2) Nếu tôi cần giữ lại đối tượng bộ điều hợp ban đầu, tôi có cần giữ đối tượng kết nối có sẵn và mở không?

Tôi hiểu mô hình đã ngắt kết nối của ADO.NET - Tôi chỉ bị nhầm lẫn về phạm vi đối tượng khi đến lúc cập nhật cơ sở dữ liệu. Nếu ai đó có thể cho tôi một vài gợi ý về các phương pháp hay nhất cho kịch bản này, tôi sẽ đánh giá cao điều đó!

Cảm ơn trước ...

Trả lời

3

1) Bạn không cần phải DataAdapter như nhau, nhưng nếu bạn tạo một hình mới nó phải sử dụng cùng một truy vấn như cơ sở của nó.

2) DataAdapter sẽ mở kết nối nếu kết nối được đóng. Trong trường hợp đó, nó sẽ đóng lại kết nối sau khi hoàn thành. Nếu kết nối đã được mở nó sẽ để kết nối mở ngay cả sau khi nó được thực hiện.

Thông thường bạn sẽ làm việc như trong ví dụ của mình. Tạo một Conneciton và một DataAdapter, điền vào một DataTable và xử lý kết nối và DataAdapter sau đó.

Hai ý kiến ​​để mã của bạn:

  • Bạn không cần CommandBuilder đây vì bạn chỉ làm một lựa chọn. Trình tạo lệnh chỉ cần thiết nếu bạn muốn tự động tạo các câu lệnh Chèn, Cập nhật hoặc Xóa. Trong trường hợp đó, bạn cũng cần phải đặt InsertCommand, UpdateCommand hoặc DeleteCommand trên DataAdapter theo cách thủ công từ CommandBuilder.
  • Thứ hai. Thay vì gọi Dispose theo cách thủ công, bạn nên sử dụng mệnh đề Using. Nó đảm bảo rằng các đối tượng của bạn sẽ được xử lý ngay cả khi một ngoại lệ được ném ra.

Cố gắng thay đổi mã của bạn như thế này:

DataTable dt = new DataTable(); 
using (OleDbConnection conn = new OleDbConnection("my_connection_string")) 
using (OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * from Employees", conn)) 
{ 
    adapter.Fill(dt);  
} 

Lưu ý rằng tôi xác định các DataTable bên ngoài các điều khoản sử dụng. Điều này là cần thiết để đảm bảo rằng bảng nằm trong phạm vi khi bạn rời khỏi sử dụng. Cũng lưu ý rằng bạn không cần phải gọi Dispose trên DataAdapter hoặc lệnh Close trên Connection. Cả hai đều được thực hiện hoàn toàn khi bạn để lại các sử dụng.

Oh.Và hoan nghênh SO :-)

+0

Bộ điều hợp dữ liệu có thể mở các kết nối ngầm, bây giờ tôi không chắc chắn về việc này bên trong một câu lệnh sử dụng, nhưng không thể bạn chỉ cần thả dòng conn.Open(), và để cho dataadaptor mở kết nối. – GordonB

+0

Điểm tốt. Tôi thậm chí còn đề cập đến nó dưới 2). :-) Tôi sẽ cập nhật mã ví dụ –

+0

Bộ điều hợp dữ liệu có thể là lựa chọn tốt trong trường hợp bán hàng triệu bản ghi (ví dụ: 2-3 triệu bản ghi mà tôi có trong dữ liệu của mình) vào cơ sở dữ liệu không ??? –

0

Để trả lời câu hỏi của bạn:

  1. Tốt nhất, bạn nên giữ lại DataAdapter cùng vì nó đã thực hiện nó khởi tạo. Một DataAdapter cung cấp các thuộc tính như SelectCommand, UpdateCommand, InsertCommand và DeleteCommand cho phép bạn thiết lập các đối tượng Command khác nhau để thực hiện các chức năng khác nhau này trên nguồn dữ liệu. Vì vậy, bạn thấy, DataAdapter là được thiết kế để được sử dụng lại cho nhiều lệnh (cho cùng một kết nối cơ sở dữ liệu). Việc bạn sử dụng CommandBuilder (mặc dù, không được khuyến nghị) tạo ra các Lệnh khác bằng cách phân tích SelectCommand, do đó cho phép bạn thực hiện Cập nhật, Xóa và Chèn bằng cách sử dụng cùng một CommandBuilder.

  2. Tốt nhất là cho phép DataAdapter xử lý ngầm các kết nối cơ sở dữ liệu. @Rune Grimstad đã được xây dựng trên hành vi tiềm ẩn này và thật hữu ích khi hiểu điều này. Lý tưởng nhất, các kết nối phải được đóng càng sớm càng tốt.

0

Có hai chi tiết bổ sung đáng để thêm vào câu trả lời tuyệt vời của Rune Grimstad.

Đầu tiên, CommandBuilder (nếu cần) thực hiện IDisposable, và do đó nên được gói trong câu lệnh 'sử dụng' của riêng nó. Đáng ngạc nhiên (ít nhất là với tôi), Xử lý DataAdapter không không xuất hiện để Vứt bỏ CommandBuilder liên quan. Vấn đề tôi quan sát được khi tôi không làm được điều này là mặc dù tôi đã gọi Dispose trên DataAdapter, và trạng thái Connection là 'Closed', tôi không thể loại bỏ một cơ sở dữ liệu tạm thời khi đã sử dụng CommandBuilder để cập nhật cơ sở dữ liệu đó.

Thứ hai, tuyên bố "... Trong trường hợp đó bạn cũng cần đặt InsertCommand, UpdateCommand hoặc DeleteCommand trên DataAdapter theo cách thủ công ..." không phải lúc nào cũng chính xác. Đối với nhiều trường hợp tầm thường, CommandBuilder sẽ tự động tạo các câu lệnh INSERT, UPDATE và DELETE đúng dựa trên câu lệnh SELECT được cung cấp cho DataAdapter và dữ liệu meta từ cơ sở dữ liệu. 'Trivial', trong trường hợp này, có nghĩa là chỉ có một bảng duy nhất được truy cập và bảng đó có một khóa chính được trả về như một phần của câu lệnh SELECT.

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