2009-05-11 27 views
9

Tôi có mã như dưới đây trong một dự án tôi đang làm việc.Dấu trang TDataset có hiệu lực trong bao lâu?

procedure TForm.EditBtnClick(Sender:TObject); 
begin 
    // Mark is form variable. It's private 
    Mark = cdsMain.GetBookmark; 
    // blabalbal 
    . 
    . 
    . 
end; 

procedure TForm.OkBtnClick(Sender:TObject); 
var 
    mistakes: Integer; 
begin 
    //Validation stuff and transaction control 
    //removed to not clutter the code 
    If cdsMain.ChangeCount <> 0 then 
    mistakes := cdsMain.AppyUpdates(-1); 
    cdsMain.Refresh; 
    try 
    cdsMain.GotoBookmark(Mark); 
    // Yes, I know I would have to call FreeBookmark 
    // but I'm just reproducing 
    except 
    cdsMain.First; 
    end; 
end; 

Cá nhân, tôi không sử dụng bookmark nhiều - ngoại trừ để định vị một tập dữ liệu mà tôi chỉ di chuyển vị trí con trỏ (để tạo ra một danh sách, điền vào một danh sách chuỗi, vv). Nếu tôi Refresh, cập nhật (đặc biệt khi bộ lọc có thể ẩn bản ghi), hãy nạp lại (Close/Open) hoặc bất kỳ thao tác nào sửa đổi dữ liệu trong tập dữ liệu, tôi không sử dụng dấu trang. Tôi thích Locate trên khóa chính (sử dụng TClientDataset, tất nhiên) hoặc yêu cầu sửa đổi các tham số.

Cho đến khi nào một dấu trang hợp lệ? Cho đến một số Refresh? Cho đến khi một Close/Open được thực hiện để nạp lại dữ liệu? Khu an toàn kết thúc ở đâu?

Cân nhắc câu trả lời tôi đang sử dụng TClientDataset với TSQLQuery (DbExpress).

Trả lời

5

Giống như cả hai c0rwinskamradt đã đề cập: hành vi dấu trang phụ thuộc vào con cháu TDataSet bạn sử dụng.

Nói chung, đánh dấu trở thành không hợp lệ trong:

  1. đóng/mở
  2. refresh (trên tập hợp dữ liệu có hỗ trợ nó)
  3. thay đổi dữ liệu (đôi khi chỉ xóa)

tôi biết 1. và 2. có thể làm mất hiệu lực dấu trang của bạn trong TClientDataSets. Tôi gần như chắc chắn rằng đối với TClientDataSets nó không quan trọng mà nhà cung cấp cơ bản được sử dụng (TSQLQuery, TIBQuery, vv).

Cách duy nhất để đảm bảo những gì hiệu quả và những gì không được thử nghiệm. Điều đó có nghĩa là bạn hoàn toàn đúng khi không sử dụng chúng: dấu trang có cơ hội nội tại không đáng tin cậy.

Để an toàn, hãy luôn gọi BookmarkValid trước khi đi tới dấu trang.

+5

Sau một số thử nghiệm, ngay cả BookmarkValid cũng chứng minh bản thân nó không đáng tin cậy. Nó xảy ra khi bạn có một bộ lọc được kích hoạt trên tập dữ liệu - nó trả về true ngay cả khi bản ghi không phù hợp với điều kiện bộ lọc. Kết quả cuối cùng là việc ném một ngoại lệ. –

1

TDataSet triển khai phương thức đánh dấu trang ảo. Mặc dù các phương thức này đảm bảo rằng bất kỳ đối tượng tập dữ liệu nào có nguồn gốc từ TDataSet trả về giá trị nếu phương thức đánh dấu được gọi, giá trị trả lại chỉ là mặc định không theo dõi vị trí hiện tại. Hậu duệ của TDataSet, chẳng hạn như TBDEDataSet, reimplement phương pháp đánh dấu để trở về giá trị có ý nghĩa như mô tả trong danh sách sau đây:

  • BookmarkValid, để xác định liệu bookmark quy định được sử dụng.
  • CompareBookmarks, để kiểm tra hai dấu trang để xem chúng có giống nhau hay không.
  • GetBookmark, để phân bổ dấu trang cho vị trí hiện tại của bạn trong tập dữ liệu.
  • GotoBookmark, để trở về một bookmark trước đó được tạo ra bởi GetBookmark
  • FreeBookmark, để giải phóng một bookmark trước đây được phân bổ bởi GetBookmark.

lấy nó từ here

+0

Cảm ơn bạn. Tôi sẽ thuật lại câu hỏi. –

+0

Thật không may tôi không nhớ câu trả lời cho câu hỏi này, kể từ khi tôi rời Delphi lập trình từ lâu. Trực giác của tôi nói với tôi, nó sẽ có giá trị cho đến khi DataSet được mở, nhưng tôi có thể nghĩ về việc thực hiện nó có thể hữu ích ngay cả sau khi mở/đóng nó. Tôi cũng có xu hướng đồng ý với câu trả lời dưới đây, vì nó chắc chắn có thể phụ thuộc vào nhà cung cấp. –

4

Cá nhân tôi hiếm khi sử dụng bookmark. Thay vào đó, tôi sử dụng id của bản ghi mà tôi đang xem và thực hiện định vị trên bản ghi khi quá trình làm mới hoàn tất. Nếu tôi cần phải lặp qua tất cả các bản ghi trong tập hợp, tôi làm điều đó bằng cách sử dụng một bản sao của tClientDataset (có con trỏ riêng của nó).

Đó là sự hiểu biết của tôi là việc triển khai dấu trang tùy thuộc vào nhà cung cấp con cháu tDataset và có thể khác nhau giữa các triển khai. Trong tập dữ liệu rất đơn giản của tôi (tBinData), tôi đã triển khai dấu trang dưới dạng số bản ghi vật lý để nó sẽ tồn tại giữa các lần làm mới miễn là bản ghi không bị xóa. Tôi không thể nói điều này đúng cho tất cả các triển khai.