dapper.net,如何刷新 ConcurrentDictionary?

Posted

技术标签:

【中文标题】dapper.net,如何刷新 ConcurrentDictionary?【英文标题】:dapper.net, how to flush ConcurrentDictionary? 【发布时间】:2012-05-04 19:19:19 【问题描述】:

我是 dapper 的新手,并计划在我的新项目中使用它。读完之后,似乎我唯一可能遇到的问题是 ConcurrentDictionary。

Dapper 缓存有关它运行的每个查询的信息,这允许它实现对象 快速处理参数。目前的实施 将此信息缓存在 ConcurrentDictionary 对象中。对象 它的存储永远不会被刷新。如果您正在生成 SQL 字符串 在不使用参数的情况下飞行,您可能会撞到内存 问题。我们可以将字典转换为 LRU 缓存。

如何避免这个问题?谁能告诉我一些代码告诉我如何以及何时刷新它?

【问题讨论】:

所以您正在即时生成 SQL 字符串? “即时生成 SQL 字符串”是什么意思?你能给我举个例子吗? SQL 字符串——您是否使用StringBuilder 动态构建它?或者它更像是一个像var sql = @"SELECT Foo FROM Bar" 这样声明的常量字符串? 我没有使用 stringbuilder,它很慢。但是我在查询中确实使用了参数:Query("select * from Thing where Name = @Name", new Name = new DbString Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true );这是否认为是即时的? 这不是即时的,它看起来不错。我怀疑这不是您的性能问题的原因。您能否详细说明性能问题的症状?例如,当直接针对数据库服务器运行时,相同的查询是否执行得更快? (通过 SQL Server Management Studio 或其他方式) 【参考方案1】:

根据上面的 cmets,这是一个即时示例:

var builder = new StringBuilder();
builder.AppendLine("SELECT Foo FROM Bar");
if (fisrtName != null || lastName != null)
    builder.AppendLine("WHERE");
if (firstName != null)
    builder.AppendLine("    Bar.FirstName = @Firstname");
if (firstName != null && lastName != null)
    builder.Append(" AND");
if (lastName != null)
    builder.AppendLine("    Bar.LastName = @LastName");
var sql = builder.ToString();

如您所见,dapper 现在将运行的实际 SQL 将根据 firstName 和/或 lastName 是否为空而有所不同。如果两者都为空,您将获得一个 SQL 字符串。如果只有firstName 不为空,你会得到另一个。如果只有lastName 不为空,你会得到另一个。最后,如果两者都不为空,您将得到第四个排列。

这就是“on-the-fly”的含义——dapper 将根据这些独特的排列进行缓存,并且在一个更复杂的场景中,很容易看出你最终会如何得到很多不同的排列,所有这些都需要独立缓存。

【讨论】:

对不起,最后一个问题。如果我更改了名称的值,我之前发布的查询。这是一个新的排列吗?有没有办法检查是否有太多查询需要刷新 ConcurrentDictionary ? 当您使用占位符(例如where Name = @Name)时,更改您传入的值(例如new Name = new DbString Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true ))非常好,这正是dapper 的用途。跨度>

以上是关于dapper.net,如何刷新 ConcurrentDictionary?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Dapper.NET 将 C# 列表插入数据库

使用Dapper.NET异步API时如何尊重CommandTimeout

如何在Dapper.Net中编写一对多查询?

Dapper.NET——轻量ORM

dapper.net 转载

dapper.net