Đó là hầu hết trong số đó. Một số điểm bổ sung cần xem xét:
- Bạn nhận được chuỗi kết nối ở đâu? Bạn không muốn mã hóa cứng khắp nơi và bạn có thể cần phải bảo mật nó.
- Bạn thường có các đối tượng khác để tạo ra cũng trước khi bạn thực sự sử dụng kết nối (
SqlCommand
, SqlParameter
, DataSet
, SqlDataAdapter
), và bạn muốn chờ đợi càng lâu càng tốt để mở kết nối. Mẫu đầy đủ cần phải tính đến điều đó.
- Bạn muốn đảm bảo quyền truy cập cơ sở dữ liệu của bạn bị buộc vào lớp hoặc lắp ráp lớp dữ liệu riêng. Vì vậy, một điều phổ biến cần làm là diễn tả điều này dưới dạng gọi hàm riêng tư:
.
private static string connectionString = "load from encrypted config file";
private SqlConnection getConnection()
{
return new SqlConnection(connectionString);
}
Và sau đó viết mẫu của bạn như thế này:
using (SqlConnection sqlConn = getConnection())
{
// create command and add parameters
// open the connection
sqlConn.Open();
// run the command
}
mẫu Đó chỉ có thể tồn tại trong lớp truy cập dữ liệu của bạn. Một cách khác là đánh dấu nó internal
và trải rộng lớp dữ liệu trên toàn bộ hội đồng. Điều chính là việc tách biệt mã cơ sở dữ liệu của bạn được thực thi nghiêm ngặt.
Một triển khai thực có thể trông như thế này:
public IEnumerable<IDataRecord> GetSomeData(string filter)
{
string sql = "SELECT * FROM [SomeTable] WHERE [SomeColumn] LIKE @Filter + '%'";
using (SqlConnection cn = getConnection())
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@Filter", SqlDbType.NVarChar, 255).Value = filter;
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return (IDataRecord)rdr;
}
}
}
}
Chú ý rằng tôi cũng đã có thể "ngăn xếp" việc tạo ra các cn
và cmd
đối tượng, và do đó làm giảm làm tổ và chỉ tạo một khối phạm vi.
Cuối cùng, hãy thận trọng khi sử dụng mã yield return
trong mẫu cụ thể này. Nếu bạn gọi phương thức và không hoàn thành DataBinding
hoặc sử dụng khác ngay lập tức, nó có thể giữ kết nối mở trong một thời gian dài. Một ví dụ về điều này là sử dụng nó để thiết lập một nguồn dữ liệu trong sự kiện Load
của một trang ASP.NET. Vì sự kiện ràng buộc dữ liệu thực sự sẽ không xảy ra cho đến sau này, bạn có thể giữ kết nối mở lâu hơn nhiều so với mức cần thiết.
Nguồn
2009-05-26 17:27:43
điểm 1: Tôi lưu trữ các chuỗi kết nối của mình trong phần của ứng dụng/web.config Điểm 2: Đây có phải là điều tôi nên lo lắng không. Tôi thường làm SqlConnection, sau đó mở nó, sau đó tạo sqlCommand của tôi và sau đó lấy nếu từ đó. Điểm 3: Chúng tôi thực hiện tất cả truy cập DB từ một lớp lib. Tôi không thích làm DB truy cập hình thức ứng dụng cốt lõi. Có đáng để tôi tạo phương thức getConnection không? –
Neale
Vì bạn sử dụng một lớp lib cho tất cả truy cập db, nó là một điều đơn giản để làm cho phần chuỗi kết nối của tệp .config của lớp lib chứ không phải tệp .config sẽ là toàn cục cho toàn bộ ứng dụng. Điều này sẽ đủ tốt để thực thi việc tách lớp dữ liệu sạch, nhưng đồng thời cũng không có lý do gì để đưa phương thức này ra công khai. Điều đó sẽ giải quyết điểm 1 & 3. Đối với điểm 2, nó có thể không làm tổn thương bất cứ điều gì để có nó mở cho một hoặc hai dòng phụ, nhưng nó không giúp đỡ một trong hai. Tôi đang chỉnh sửa bằng một lý do khác mà bạn có thể muốn thực hiện theo cách đó. –
Ví dụ về 'lợi nhuận của bạn' hơi gây hiểu nhầm. Một hàm được xây dựng xung quanh 'return yield' không bắt đầu thực thi cho đến lần gọi đầu tiên của' MoveNext() 'trên' IEnumerator'. Vì vậy, ngay cả khi bạn gọi hàm, kết nối sẽ không được mở cho đến khi bạn bắt đầu lặp lại kết quả. –