我一直在與彼得蒙哥馬利的試驗「緩存LINQ查詢的結果」源上市here從緩存列表查詢的IQUERY返回null例外
這創造了IQueryable<T>
的擴展方法從緩存的數據,如果返回的IEnumerable<T>
可能。主擴展方法看起來像這樣。
/// <summary>
/// Returns the result of the query; if possible from the cache, otherwise
/// the query is materialized and the result cached before being returned.
/// </summary>
/// <param name="query">The IQueryable for which to return the query.</param>
/// <param name="priority">The relative cache priority of the object.</param>
/// <param name="slidingExpiration">The timespan indicating the duration of the sliding expiration</param>
/// <returns>The result of the query; if possible from the cache</returns>
/// <typeparam name="T">The type of entity for which to provide the method.</typeparam>
public static IEnumerable<T> FromCache<T>(this IQueryable<T> query, CacheItemPriority priority, TimeSpan slidingExpiration)
{
string key = query.GetCacheKey();
// try to get the query result from the cache
var result = HttpRuntime.Cache.Get(key) as List<T>;
if (result == null)
{
// TODO: ... ensure that the query results do not
// hold on to resources for your particular data source
//
//////// for entity framework queries, set to NoTracking
//////var entityQuery = query as ObjectQuery<T>;
//////if (entityQuery != null)
//////{
////// entityQuery.MergeOption = MergeOption.NoTracking;
//////}
// materialize the query
result = query.ToList();
HttpRuntime.Cache.Insert(
key,
result,
null, // no cache dependency
Cache.NoAbsoluteExpiration,
slidingExpiration,
priority,
null); // no removal notification
}
return result;
}
我使用的方法是這樣的:
/// <summary>
/// Retrieves all instances of the specified type, if possible from the cache.
/// Objects are maintained in a <see cref="T:System.Data.EntityState.Detached">Detached</see> state and
/// are not tracked in the <see cref="T:System.Data.Objects.ObjectStateManager">ObjectStateManager</see>.
/// </summary>
/// <returns>A list of all instances of the specified type.</returns>
/// <typeparam name="T">The type of entity for which to provide the method.</typeparam>
public IQueryable<T> All<T>() where T : class, new()
{
//return new ObjectQuery<T>(GetSetName<T>(), this.context, MergeOption.NoTracking);
return new ObjectQuery<T>(GetSetName<T>(), this.context, MergeOption.NoTracking).FromCache<T>().AsQueryable<T>();
}
我會再篩選我的要求是這樣的(查詢AdventureWorks數據庫樣本):
List<Product> products = new List<Product>(readonlySession.All<Product>()
.Where(x => x.Color.Equals("Black", StringComparison.InvariantCultureIgnoreCase)));
我的問題是,當我嘗試查詢這樣的數據,我得到一個NullReferenceException
,因爲一些產品返回null爲屬性Color
。如果我查詢沒有緩存的實體,那就沒有問題了。
任何人都可以解釋爲什麼發生這種情況,我該如何解決這個問題?
非常感謝。
更新:自從我發現使用==解決了我的問題,但我不知道爲什麼。我希望能夠使用Equals()。
@ķ伊萬諾夫:謝謝你的解釋。我不能接受你的答案的唯一原因是你被打了一段時間。儘管我已經投了票。 – 2011-01-30 19:00:34
thx,雖然我的回答是在你選擇的那個之前4分鐘,但這不是什麼大問題 – 2011-01-30 19:04:35