SqlDataAd CHƯƠNG vs SqlDataReader


130

Sự khác biệt giữa việc sử dụng SqlDataAdOG so với SqlDataReader để nhận dữ liệu từ DB là gì?

Tôi đặc biệt xem xét ưu và nhược điểm của họ cũng như tốc độ và hiệu suất bộ nhớ của họ.

Cảm ơn

Câu trả lời:


193

SqlDataReader:

  • Giữ kết nối mở cho đến khi bạn kết thúc (đừng quên đóng nó!).
  • Thông thường chỉ có thể được lặp đi lặp lại một lần
  • Không hữu ích cho việc cập nhật trở lại cơ sở dữ liệu

Mặt khác, nó:

  • Chỉ có một bản ghi trong bộ nhớ tại một thời điểm chứ không phải toàn bộ tập kết quả (điều này có thể là LỚN )
  • Nhanh như bạn có thể nhận được cho một lần lặp đó
  • Cho phép bạn bắt đầu xử lý kết quả sớm hơn (khi bản ghi đầu tiên khả dụng). Đối với một số loại truy vấn, đây cũng có thể là một vấn đề rất lớn.

SqlDataAdOG / Dataset

  • Cho phép bạn đóng kết nối ngay khi tải xong dữ liệu và thậm chí có thể tự động đóng nó cho bạn
  • Tất cả các kết quả có sẵn trong bộ nhớ
  • Bạn có thể lặp đi lặp lại nhiều lần nếu cần hoặc thậm chí tra cứu một bản ghi cụ thể theo chỉ mục
  • Có một số khoa tích hợp để cập nhật trở lại cơ sở dữ liệu

Với chi phí:

  • Sử dụng bộ nhớ cao hơn nhiều
  • Bạn đợi cho đến khi tất cả dữ liệu được tải trước khi sử dụng bất kỳ dữ liệu nào

Vì vậy, thực sự nó phụ thuộc vào những gì bạn đang làm, nhưng tôi có xu hướng thích DataReader cho đến khi tôi cần thứ gì đó chỉ được hỗ trợ bởi một bộ dữ liệu. SqlDataReader là hoàn hảo cho trường hợp truy cập dữ liệu phổ biến liên kết với lưới chỉ đọc.

Để biết thêm thông tin, xem tài liệu chính thức của Microsoft .


5
Bộ dữ liệu là kho dữ liệu trong bộ nhớ, trong khi bộ dữ liệu chỉ là phương tiện để truy xuất dữ liệu. Trên một ghi chú nhẹ hơn, bạn có thể chạy các truy vấn Linq trên Dataset, nhưng không phải trên bộ dữ liệu.
Partha Choudhury

Trên thực tế, với một chút mã bổ sung, bạn chắc chắn có thể chạy các truy vấn linq (hoặc, ít nhất một truy vấn) trên bộ dữ liệu. Chỉ cần sử dụng khối lặp để mang lại kết quả DataReader dưới dạng IDataRecord trong while (reader.Read())vòng lặp của bạn .
Joel Coehoorn

7
Câu trả lời này là sai lệch. Nếu bạn bọc các đối tượng SqlConnection và SqlDataReader của bạn bằng các câu lệnh "bằng cách sử dụng" (vì dù sao bạn cũng nên, vì chúng là IDis Dùng một lần), kết nối sẽ tự động bị đóng. Và bạn có thể sử dụng một Dataset với SqlDataReader: chỉ cần gọi DataSet.Load (SqlDataReader).
RickNZ

4
@RickNZ Đừng quá tin tưởng sử dụng các câu lệnh để đóng mọi thứ cho bạn. Họ gọi phương thức Dispose () của đối tượng, không phải là phương thức Close () và tôi đã gặp phải ít nhất một trường hợp trong đó Dispose không thực sự đóng đối tượng cho tôi. Luôn luôn tốt nhất là bao gồm một cuộc gọi rõ ràng đến phương thức đóng bên trong khối sử dụng.
Cdaragorn

5
@Cdaragorn các tài liệu MSDN thường khá rõ ràng về Đóng () so với Dispose (). Ví dụ, trong trường hợp của SqlConnection, các tài liệu nói rằng Close () và Dispose () tương đương về chức năng. Tôi không phản đối việc gọi Close (), nhưng các cuộc gọi đến Dispose () cũng sẽ có ở đó cho tất cả các IDisposeables - và cách rõ ràng nhất để thực hiện điều đó là bằng câu lệnh sử dụng. Trong trường hợp bạn biết Dispose () không gọi Close (), thì bạn nên gọi Close () trong một khối cuối cùng nếu bạn có thể, không nằm trong khối sử dụng (vì vậy nó vẫn được gọi nếu có ngoại lệ).
RickNZ

17

Câu trả lời cho điều đó có thể khá rộng.

Về cơ bản, sự khác biệt lớn đối với tôi thường ảnh hưởng đến quyết định sử dụng của tôi là với SQLDataReader, bạn đang "truyền phát" dữ liệu từ cơ sở dữ liệu. Với SQLDataAd CHƯƠNG, bạn đang trích xuất dữ liệu từ cơ sở dữ liệu vào một đối tượng có thể tự truy vấn thêm, cũng như thực hiện các thao tác CRUD trên.

Rõ ràng với một luồng dữ liệu SQLDataReader nhanh hơn NHIỀU, nhưng bạn chỉ có thể xử lý một bản ghi tại một thời điểm. Với SQLDataAd CHƯƠNG, bạn có một bộ sưu tập đầy đủ các hàng khớp với truy vấn của bạn từ cơ sở dữ liệu để làm việc với / chuyển qua mã của bạn.

CẢNH BÁO: Nếu bạn đang sử dụng SQLDataReader, LUÔN LUÔN, LUÔN LUÔN, LUÔN LUÔN đảm bảo rằng bạn viết mã phù hợp để đóng kết nối vì bạn đang giữ kết nối mở với SQLDataReader. Không làm điều này hoặc xử lý lỗi thích hợp để đóng kết nối trong trường hợp xảy ra lỗi khi xử lý kết quả sẽ CRIPPLE ứng dụng của bạn bị rò rỉ kết nối.

Xin lỗi VB của tôi, nhưng đây là số lượng mã tối thiểu bạn nên có khi sử dụng SqlDataReader:

Using cn As New SqlConnection("..."), _
      cmd As New SqlCommand("...", cn)

    cn.Open()
    Using rdr As SqlDataReader = cmd.ExecuteReader()
        While rdr.Read()
            ''# ...
        End While
    End Using
End Using     

tương đương C #:

using (var cn = new SqlConnection("..."))
using (var cmd = new SqlCommand("..."))
{
    cn.Open();
    using(var rdr = cmd.ExecuteReader())
    {
        while(rdr.Read())
        {
            //...
        }
    }
}

Nếu mục tiêu của bạn là lấy dữ liệu bằng cách sử dụng truy vấn chọn lọc trên db và chỉ truy cập dữ liệu này ở các hàng khác nhau, hãy chuyển đến hàng có thể sử dụng, v.v. Sau đó duyệt lên và xuống trong phạm vi dữ liệu này. Bạn có thể sử dụng phương thức này thay vì DataAd CHƯƠNG ...
biến

14

Một SqlDataAd CHƯƠNG thường được sử dụng để điền vào Dataset hoặc DataTable và do đó bạn sẽ có quyền truy cập vào dữ liệu sau khi kết nối của bạn bị đóng (truy cập bị ngắt kết nối).

SqlDataReader là một con trỏ chỉ được kết nối và chuyển tiếp nhanh, thường có xu hướng nhanh hơn so với việc điền vào một Dataset / DataTable.

Hơn nữa, với SqlDataReader, bạn xử lý từng bản ghi dữ liệu của mình và không giữ bất kỳ dữ liệu nào trong bộ nhớ. Rõ ràng với DataTable hoặc Dataset, bạn có chi phí cấp phát bộ nhớ.

Nếu bạn không cần giữ dữ liệu của mình trong bộ nhớ, vì vậy chỉ để hiển thị nội dung, hãy truy cập SqlDataReader. Nếu bạn muốn xử lý dữ liệu của mình theo cách bị ngắt kết nối, hãy chọn DataAd CHƯƠNG để điền vào một Data set hoặc DataTable.


10

Sử dụng một SqlDataAd CHƯƠNG khi muốn điền một Data set / DataTable trong bộ nhớ từ cơ sở dữ liệu. Sau đó, bạn có thể linh hoạt đóng / tắt kết nối, chuyển dữ liệu / thiết lập xung quanh trong bộ nhớ. Sau đó, bạn có thể thao tác dữ liệu và lưu lại dữ liệu đó vào DB bằng bộ điều hợp dữ liệu, kết hợp với insertCommand / UpdateCommand.

Sử dụng SqlDataReader khi muốn truy cập dữ liệu dấu chân nhanh, bộ nhớ thấp mà không cần linh hoạt, ví dụ như truyền dữ liệu xung quanh logic nghiệp vụ của bạn. Điều này tối ưu hơn cho việc truy xuất nhanh, sử dụng bộ nhớ thấp với khối lượng dữ liệu lớn vì nó không tải tất cả dữ liệu vào bộ nhớ trong một lần - với cách tiếp cận SqlDataAd CHƯƠNG, Data set / DataTable sẽ được lấp đầy với tất cả dữ liệu vì vậy nếu có rất nhiều hàng và cột, sẽ cần rất nhiều bộ nhớ để giữ.


0

Hàm Fill sử dụng DataReader trong nội bộ. Nếu sự cân nhắc của bạn là "Cái nào hiệu quả hơn?", Thì việc sử dụng DataReader trong một vòng lặp chặt chẽ sẽ tạo ra một bản ghi bộ sưu tập, có khả năng sẽ tải cùng hệ thống với việc sử dụng DataAd CHƯƠNG.Fill.

(System.Data.dll, System.Data.Common.DbDataAd CHƯƠNG, FillI Internalal.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.