gpt4 book ai didi

asp.net-mvc - 如何强制 Lazy 对象创建/重新创建值?

转载 作者:行者123 更新时间:2023-12-03 02:11:11 27 4
gpt4 key购买 nike

我尝试使用 Lazy< SelectList > 来延迟缓存 ASP.NET MVC 项目中的任何查找数据。但我无法强制 Lazy 对象在更改时重新加载查找数据。

我创建派生类,如以下代码。我发现 Lazy< T > 使用 IsValueCreated 属性来保持当前状态。但是,在 MappingFunc 方法中,我无法更改 IsValueCreated 的值,因为它是静态方法。

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);
};
}
}

我使用下面的代码调用这个函数。但它总是创造新的值,因为 IsValueCreated 值始终为 false。

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

最佳答案

经过几个小时的搜索和测试,我认为不可能重置惰性对象的状态。但我可以创建包装器来处理这个问题。包装类包含惰性对象和创建新惰性对象所需的对象。代码应该是这样的。

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);
};
}
}

上面的代码允许我们重置对象的状态,以强制它为定义的函数检索新数据。

之后,我尝试使用上述方法在 ASP.NET MVC 中缓存 SelectList 对象。但它总是从数据库中检索新的,因为 SelectList 将包含 IEnumerable 对象而不是真实的对象数据。因此,我通过将数据枚举到临时对象列表中来解决问题,如下所示。

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。所有源代码都是我的 Higgs RIA 框架的一部分,可在 Codeplex 网站上找到。

LazyCache.cs | LazyList.cs

关于asp.net-mvc - 如何强制 Lazy<T> 对象创建/重新创建值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4897405/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com