第二级缓存EF代码First和Predicate不在where子句上工作

时间:2013-12-24 17:00:26

标签: entity-framework caching entity-framework-4.1

我有一个关于首先使用Entity Framework代码进行缓存的问题。 我需要缓存查询的结果,然后我发现了一些我不知道的事情。

Func<T, bool>谓词进行过滤时,

Expression<Func<T, bool>>谓词不起作用。

也许我错过了显而易见的事情。

以下是我的情景:

每当我调用一个方法,例如“GetOrders”时,我会在内部使用一个名为“GetCachedModels”的方法来获取缓存版本。

随后进行了多次通话 “GetOrders(customerNo)”它检查缓存并从那里获取它,如果它在那里。这就是理论。

然而,当使用Func谓词时,它找不到该项,但是在使用Expression版时它会这样做吗?

我的问题是如何在列表中使用Where表达式的“表达式”? 另一种解决方案是为每个搜索提供一种方法,例如“myservice.GetCustomer(etc ..)或myservice.GetOrders(etc ..)而不是泛型 myservice.GetAll();这意味着在界面中添加了许多方法。

mycode的:

public interface IGenericRepository
    {
        IList<T> GetAll<T>() where T : class;
        IList<T> Find<T>(Func<T, bool> predicate) where T : class; //I use this so that I could use the predicate in an where clause against a list.
        etc....

    }

在我的存储库中,我有类似的内容:

 public IList<T> Find<T>(Func<T, bool> predicate) where T : class
    {
        List<T> models = GetCachedModels<T>().ToList();  
        var result= models.Where(predicate).ToList();  --Does not work!!! tried also with(expression.Compile()).ToList(); !!still no results!!!!
        return result;
    }




internal IList<T> GetCachedModels<T>() where T : class
    {
        IList<T> models;                
        Type typeParameterType = typeof(T);
        string cacheName = string.Format("{0}Cache", typeParameterType.Name);
        object cacheView = DbCache.Get(cacheName);
        if (cacheView == null)
        {
            models = Set<T>().ToList();
            DbCache.Add(cacheName, models, DateTime.Now.AddHours(1));
        }
        else
        {
            models = (IList<T>)cacheView;
        }
        return models;
    }


    //below method works but cannot use cache!!!!

    public IList<T> Find<T>(Expression<Func<T, bool>> predicate) where T : class
    {
        return Set<T>().Where(predicate).ToList();
    }

1 个答案:

答案 0 :(得分:0)

表达式谓词仅适用于IQueryable接口。 List不会继承它,所以如果你想使用这个表达式,你需要在GetCachedModels方法中返回IQueryable,并返回Set,这样它就可以查询这些数据。然后你可以放置它。

否则,如果要缓存Set中的所有项目,则需要传递Func而不是Expression,然后在Where扩展方法中使用它,如下所示 - http://dotnetfiddle.net/5YsIy3