如何在 Linq to SQL 中实现缓存?
Posted
技术标签:
【中文标题】如何在 Linq to SQL 中实现缓存?【英文标题】:How do you implement caching in Linq to SQL? 【发布时间】:2010-09-07 10:23:35 【问题描述】:我们刚刚开始在我们的 DAL 中使用 LINQ to SQL,我们还没有真正想出一个用于输出缓存模型的标准。以前我们一直在使用一个基本的“DAL”类,它实现了我们所有的 DAL 类都继承自的缓存管理器属性,但现在我们没有了。我想知道是否有人提出了一种“标准”方法来缓存 LINQ to SQL 结果?
如果这会产生影响,我们正在使用 Web 环境 (IIS)。我知道这很可能最终成为subjective 问题,但我仍然认为这些信息很有价值。
编辑:澄清一下,我不是在谈论缓存单个结果,我更多的是一种架构解决方案,例如如何设置缓存以便所有链接方法使用相同的缓存架构。
【问题讨论】:
【参考方案1】:我的LINQ query result cache 可能正是您想要的。
var q = from c in context.Customers
where c.City == "London"
select new c.Name, c.Phone ;
var result = q.Take(10).FromCache();
皮特。
【讨论】:
那是一段很棒的代码,像这样的东西需要构建到框架中。 现在是 2017 年,我正在寻找类似的解决方案,发现了这个 github.com/zzzprojects/EntityFramework-Plus 项目【参考方案2】:快速回答:使用存储库模式(请参阅 Evans 的域驱动设计)来获取您的实体。每个存储库都会缓存它所持有的东西,理想情况下是让存储库的每个实例访问一个单例缓存(每个线程/请求都会实例化一个新的存储库,但只能有一个缓存)。
以上答案仅适用于一台机器。为了能够在许多机器上使用它,请使用 memcached 作为您的缓存解决方案。祝你好运!
【讨论】:
请注意,这种方法与 LINQ 或 LINQ to SQL 并没有太大关系。基于存储库的 API 不能与进一步的 LINQ 查询组合。 您应该在使用存储库模式时关闭对象跟踪。否则,这将由存储库自行决定:repository.Get(1).ReferencedTable.Id
...因为“.ReferencedTable”将很难在没有上下文的情况下查找缓存列表。【参考方案3】:
就在你的鼻子底下:
List<TableItem> myResult = (from t in db.Table select t).ToList();
现在,只需缓存 myResult,就像缓存旧 DAL 返回的数据一样。
【讨论】:
【参考方案4】:我找到了this post,它提供了一种扩展方法来缓存 LINQ 对象。
我一直在为弱者撞墙,现在试图为 Linq2SQL 找出一个好的缓存解决方案,必须承认我真的很难找到一个万能的...
存储库模式往往会限制 Linq 的实用性,因为(无需重新实现 IQueryable)缓存必须在 Linq 语句之外执行。
此外,如果您要缓存对象,延迟加载和对象跟踪都是大忌,这使得执行更新有些棘手。
任何在一个高度并发的 Web 项目中设法解决这个问题的人,请加入并拯救世界! :)
【讨论】:
【参考方案5】:我知道这个答案可能有点晚了......不过,您可以尝试LinqToCache 项目。如果可能,它会在任意 LINQ 查询上挂钩 SqlDepdency,并通过服务器端查询通知提供活动缓存失效。查询必须是通知的有效查询,请参阅Creating a Query for Notification。大多数 Linq-to-sql 查询都符合这些限制,只要表是使用两部分名称指定的(dbo.Table
,而不仅仅是Table
)。
【讨论】:
我已经设置了一个带有单个表(请求)的基本 L2S 模型,我正在尝试使用 LinqToCache 进行基本查询from r in ctx.Requests select r
。但是,它一直失败,除了When using SqlDependency without providing an options value, SqlDependency.Start() must be called prior to execution of a command added to the SqlDependency instance.
有什么想法吗?
@James:打电话给SqlDependency.Start ()
?
我的错,我愚蠢地认为AsCached
在内部触发了SqlDependency.Start()
...然后意识到这毫无意义!现在可以了,谢谢。顺便说一句,干得好,将来与 E2F 合作有希望吗?
@James:我还没有检查 EF4 在做什么,但很快就可以工作的机会很小......
遗憾的是,L2S 对我的需要同样适用。另一个简单的问题 - 在 CachedQueryOptions 中,UtcQueryTime
用于什么?我正在尝试实现一个选择查询,该查询仅返回自上次更新以来较新的记录。我想知道这是否用于此目的?【参考方案6】:
请参阅this article 中“ReferenceData”类中的“GetReferenceData”方法: http://blog.huagati.com/res/index.php/2008/06/23/application-architecture-part-2-data-access-layer-dynamic-linq/
它使用 asp.net 页面缓存来缓存使用 L2S 检索到的数据。
【讨论】:
以上是关于如何在 Linq to SQL 中实现缓存?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Entity Framework Core 2.0 上的 lambda 语法在 LINQ 中实现 LEFT OUTER JOIN?