2011-02-04 23 views
9

Tôi cố gắng để Lazy < SelectList> để lưu trữ bộ nhớ đệm chậm bất kỳ dữ liệu tra cứu nào trong dự án ASP.NET MVC của tôi. Nhưng tôi không thể ép buộc đối tượng Lazy tải lại dữ liệu tra cứu khi nó được thay đổi.Làm thế nào để buộc đối tượng <T> lười biếng để tạo/tái tạo giá trị?

Tôi tạo lớp dẫn xuất như mã sau. Tôi thấy rằng Lazy < T> sử dụng thuộc tính IsValueCreated để giữ trạng thái hiện tại. Tuy nhiên, trong phương thức MappingFunc tôi không thể thay đổi giá trị của IsValueCreated vì nó là phương thức tĩnh.

public class LazySelectList : Lazy<SelectList> 
{ 
    public LazySelectList(Func<LimeEntities, IEnumerable> initFn, string dataValueField, string dataTextField) 
     : base(MapingFunc(initFn, dataValueField, dataTextField)) 
    { 
    } 

    public new bool IsValueCreated { get; set; } 

    public static Func<SelectList> MapingFunc(Func<DbContext, IEnumerable> valueFactory, string dataValueField, string dataTextField) 
    { 
     return() => 
     { 
      var context = ObjectFactory.GetInstance<DbContext>(); 

      return new SelectList(valueFactory(context), dataValueField, dataTextField); 
     }; 
    } 
} 

Tôi sử dụng mã bên dưới để gọi hàm này. Nhưng nó luôn tạo ra giá trị mới bởi vì giá trị IsValueCreated luôn luôn là sai.

LookupCache.DocTypeList = new LazySelectList(db => db.DocTypes.OrderBy(x => x.Name), "ID", "Name"); 
+1

Bản sao có thể có của http://stackoverflow.com/questions/5961252/reset-system-lazy/ – Olmo

Trả lời

10

Sau vài giờ để tìm kiếm thử nghiệm &, tôi nghĩ không thể đặt lại trạng thái của đối tượng lười. Nhưng tôi có thể tạo trình bao bọc để xử lý vấn đề này. Lớp wrapper chứa đối tượng lười và đối tượng cần thiết để tạo đối tượng lười biếng mới. Mã nên được như thế này.

public class LazyCache<TSource, TModel> : IValue<TModel> 
{ 
    private Lazy<TModel> _lazyObj; 
    private readonly Func<TSource, TModel> _valueFactory; 

    protected LazyCache() 
    { 
     Reset(); 
    } 

    public LazyCache(Func<TSource, TModel> valueFactory) : this() 
    { 
     _valueFactory = valueFactory; 
    } 

    public void Reset() 
    { 
     _lazyObj = new Lazy<TModel>(MapingFunc()); 
    } 

    public TModel Value 
    { 
     get { return _lazyObj.Value; } 
    } 

    protected virtual Func<TModel> MapingFunc() 
    { 
     return() => 
     { 
      var context = ObjectFactory.GetInstance<TSource>(); 

      return _valueFactory(context); 
     }; 
    } 
} 

Mã trên cho phép chúng tôi đặt lại trạng thái của đối tượng để buộc truy xuất dữ liệu mới cho hàm đã xác định.

Sau đó, tôi cố gắng sử dụng phương pháp trên để lưu trữ đối tượng SelectList trong ASP.NET MVC. Nhưng nó luôn luôn lấy mới từ cơ sở dữ liệu vì SelectList sẽ chứa đối tượng IEnumerable thay vì dữ liệu đối tượng thực. Vì vậy, tôi giải quyết vấn đề bằng cách liệt kê dữ liệu vào danh sách đối tượng temp như lớp sau.

public class LazyList<TSource> : LazyCache<TSource, SelectList> 
{ 
    private readonly Func<TSource, IEnumerable> _valueFactory; 
    private readonly string _dataValueField; 
    private readonly string _dataTextField; 

    public LazyList(Func<TSource, IEnumerable> valueFactory, string dataValueField, string dataTextField) 
    { 
     _valueFactory = valueFactory; 
     _dataValueField = dataValueField; 
     _dataTextField = dataTextField; 
    } 

    protected override Func<SelectList> MapingFunc() 
    { 
     return() => 
     { 
      var context = ObjectFactory.GetInstance<TSource>(); 

      // Force to retrieve data from current IEnumerable to prevent lazy loading data that 
      // cause system always connect to database every time they generate data from selectlist. 
      var loop = _valueFactory(context).GetEnumerator(); 
      var tempList = new List<object>(); 

      while (loop.MoveNext()) 
      { 
       tempList.Add(loop.Current); 
      } 

      return new SelectList(tempList, _dataValueField, _dataTextField); 
     }; 
    } 
} 

PS. Tất cả các mã nguồn là một phần của khuôn khổ Higgs RIA của tôi có sẵn trên trang web Codeplex.

LazyCache.cs | LazyList.cs

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