缓存Linq查询 - 这可能吗?

Tej*_*ejs 5 c# linq caching iterator deferred-execution

所以,这似乎是一个边缘情况,但我只是想知道这是否可能.我所拥有的是静态集和延迟集的组合IEnumerable- 例如:

public IEnumerable<T> MakeMyQuery<T>()
{
    // returns a List<T>
    var someStaticData = LoadMyStaticDataFromDatabase();

    // Returns IEnumerable<T>, but from another resource
    var deferredQuery = CreateADeferredQueryUsingYieldReturn(); 

    return someStaticData.Concat(deferredQuery);
}
Run Code Online (Sandbox Code Playgroud)

所以这里发生的是当我调用.Take(someNumber)我的枚举时,它会在尝试评估延迟组件之前首先从我的静态数据返回元素 - 实际上,我已经"隐藏"了一些可能耗时的生成任务后面的任务,如果我从来不需要获取这些元素,因为LINQ的延迟特性,它们实际上永远不会被评估.

但是,我不认为可以缓存此查询以供以后使用(我不相信Iterator的状态将保留在缓存中,对吧?)或者是否有一种简单的方法可以在不将结果枚举到保存?

理想情况下,我的流程是这样的:

public List<T> SomeMethod<T>(int numberOfGuys)
{
     IEnumerable<T> query = null;

     if(// Is in Cache)
       query = Cache["MyQuery"];
     else
     {
         query = MakeMyQuery();
         Cache["MyQuery"] = query;
     }

     return query.Take(numberOfGuys).ToList();
}
Run Code Online (Sandbox Code Playgroud)

所以我可以反复使用相同的查询来请求数据,但可能永远不必重新查询数据库.有没有办法做到这一点?

Jac*_*coy 2

我认为您想将结果缓存query.Take(numberOfGuys).ToList()在新列表中。在调用之前,MakeMyQuery()您可以查看缓存列表中的元素数量(如果存在),如果缓存列表中的元素数量大于或等于,则您将从缓存列表中numberOfGuys返回。numberOfGuys否则,您将用 的新结果替换缓存列表query.Take(numberOfGuys).ToList()

正如 default.krammer 指出的那样,您可能真正想要缓存的结果是LoadMyStaticDataFromDatabase()因为 ifnumberOfGuys始终小于LoadMyStaticDataFromDatabase(),您最终将重复访问数据库,直到numberOfGuys大于 所返回的数字LoadMyStaticDataFromDatabase()LoadMyStaticDataFromDatabase()因此,您可以在方法中进行缓存MakeMyQuery<T>(),并query.Take(numberOfGuys).ToList()在 中进行缓存SomeMethod<T>(int numberOfGuys),这将允许您只访问数据库一次,但仍然可以利用IEnumerable<T>.