2008-08-28 33 views
11

Vì vậy, tôi vừa sửa một lỗi trong một khung công tác mà tôi đang phát triển. Các giả giả trông như thế này:Mẫu Caching trong ASP.NET

myoldObject = new MyObject { someValue = "old value" }; 
cache.Insert("myObjectKey", myoldObject); 
myNewObject = cache.Get("myObjectKey"); 
myNewObject.someValue = "new value"; 
if(myObject.someValue != cache.Get("myObjectKey").someValue) 
    myObject.SaveToDatabase(); 

Vì vậy, về cơ bản, tôi đã nhận được một đối tượng từ bộ nhớ cache, và sau đó trên so sánh các đối tượng ban đầu để các đối tượng được lưu trữ để xem nếu tôi cần phải lưu nó vào cơ sở dữ liệu trong trường hợp nó thay đổi. Vấn đề nảy sinh bởi vì đối tượng ban đầu là một tham chiếu ... vì vậy việc thay đổi someValue cũng đã thay đổi đối tượng được lưu trữ tham chiếu, vì vậy nó sẽ không bao giờ lưu lại cơ sở dữ liệu. Tôi cố định nó bằng cách nhân bản đối tượng ra khỏi phiên bản được lưu trong bộ nhớ cache, cắt đứt tham chiếu và cho phép tôi so sánh đối tượng mới với đối tượng được lưu trong bộ nhớ cache.

Câu hỏi của tôi là: có cách nào tốt hơn để thực hiện việc này không, một số mẫu mà bạn có thể đề xuất? Tôi không thể là người duy nhất được thực hiện việc này trước đây :)

Trả lời

20

Theo dõi bẩn là cách thông thường để xử lý việc này, tôi nghĩ vậy. Một cái gì đó như:

class MyObject { 
    public string SomeValue { 
    get { return _someValue; } 
    set { 
     if (value != SomeValue) { 
      IsDirty = true; 
      _someValue = value; 
     } 
    } 

    public bool IsDirty { 
    get; 
    private set; 
    } 

    void SaveToDatabase() { 
    base.SaveToDatabase(); 
    IsDirty = false; 
    } 
} 

myoldObject = new MyObject { someValue = "old value" }; 
cache.Insert("myObjectKey", myoldObject); 
myNewObject = cache.Get("myObjectKey"); 
myNewObject.someValue = "new value"; 
if(myNewObject.IsDirty) 
    myNewObject.SaveToDatabase(); 
+0

Có rất nhiều điều mà tôi không biết về ngôn ngữ và cú pháp. 1 bởi vì tôi đã học được rằng bạn có thể làm cho một setter riêng tư bên trong một tài sản công cộng. Awesomeness xảy ra sau đó! – theo

+0

@theo: Chỉ trong các phiên bản sau của .NET (Tôi tin 2.0+, có thể 3.0?) – Broam

1

Tôi đã làm những việc tương tự, nhưng tôi đã giải quyết nó bằng cách sao chép quá. Sự khác biệt là tôi đã có bộ nhớ đệm làm nhân bản. Khi bạn đặt một đối tượng vào bộ nhớ cache, bộ đệm sẽ nhân bản đối tượng đầu tiên và lưu trữ phiên bản nhân bản (để bạn có thể thay đổi đối tượng gốc mà không bị nhiễm độc bộ đệm). Khi bạn lấy một đối tượng từ cache, cache sẽ trả về một bản sao của đối tượng thay vì đối tượng được lưu trữ (một lần nữa để người gọi có thể thay đổi đối tượng mà không ảnh hưởng đến đối tượng được lưu trữ/chuẩn).

Tôi nghĩ rằng điều này là hoàn toàn chấp nhận được miễn là dữ liệu bạn đang lưu trữ/lừa đảo là nhỏ.

1

Một cải tiến nhỏ trên Marks anwser khi sử dụng LINQ:

Khi sử dụng LINQ, lấy thực thể từ DB sẽ đánh dấu tất cả các đối tượng như IsDirty. Tôi đã giải quyết vấn đề này, bằng cách không thiết lập IsDirty khi giá trị không được đặt; cho trường hợp này: khi null. Đối với ints, tôi đặt giá trị orig thành -1 và sau đó kiểm tra. Điều này sẽ không hoạt động, tuy nhiên, nếu giá trị được lưu là giống như giá trị uninitialized (null trong ví dụ của tôi).

private string _name; 
[Column] 
public string Name 
{ 
    get { return _name; } 
    set 
    { 
     if (value != _name) 
     { 
      if (_name != null) 
      { 
       IsDirty = true; 
      } 
      _name = value; 
     } 
    } 
} 

Có thể được cải thiện thêm bằng cách đặt IsDirty sau khi khởi tạo bằng cách nào đó.