使用 dapper 替换成熟的 OR/M
Posted
技术标签:
【中文标题】使用 dapper 替换成熟的 OR/M【英文标题】:using dapper to replace a fully fledged OR/M 【发布时间】:2012-05-01 18:04:36 【问题描述】:Dapper micro OR/M 给我留下了深刻的印象,我真的很想将它用作一些完全成熟的 OR/M 的并排伴侣,并最终取代它。无论如何,我没有弄清楚是否有一些策略可以从 db 反序列化层次结构:例如,记录集行的返回对象将取决于一个字段(例如,NH 中所谓的“鉴别器”)。此外,层次结构可以通过连接拆分更多表,因此表示行的类型将取决于另一个表中记录的存在。具有由上述两种策略的混合表示的层次结构将是 NH 不支持的,但存在于“关系生活”中。所以问题:
Dapper 能处理这种情况吗? 这种情况是否会在性能方面削弱 Dapper 的努力?另一个主题是缓存。用于查询的 Dapper 缓存有点激进,最好有一些“类似于上下文的会话”并为每个会话都有一个查询缓存,或者这会再次冒犯 Dapper 的主要动机吗?
【问题讨论】:
【参考方案1】:目前 Dapper 不支持自定义构造逻辑,我猜你要求的是这样的:
class Post
class Question : Post ..
class Answer : Post ...
Func<IDbDataReader, Func<IDbDataReader, Post>> factoryLocator
= ... my magic factory locater;
cnn.Query<Post>(@"
select * from Posts p
left join Questions q on q.Id = p.Id
left join Answers a on a.Id = p.Id", factoryLocator: factoryLocator);
我们决定不实施这样的逻辑,因为我们在现实生活中从未真正需要解决这样的问题。它还引入了相当多的内部复杂性和相当多的外部复杂性(因为您需要打开post is Question
)。
如果你能提出一个很好的理由来支持包含这种功能并且补丁很简单,我不会断然反对包含这种功能。我也完全赞成在 Dapper 中添加钩子以允许您注入这种功能。
关于缓存策略,我们发现在一般使用中我们永远不会使缓存膨胀,只有当您误用 dapper 时才会发生膨胀,例如生成未参数化的 SQL。我完全支持添加一个允许您指定自己的缓存提供程序而不是现在使用的ConcurrentDictionary
的钩子。
【讨论】:
谢谢!我同意缓存,通过进一步使用/查看代码,我认为没有真正需要另一个。如果我下一个项目从 NH 转移到 dapper,我将遇到子类化问题,我会尝试解决,也许在 POCO 上有一个静态方法,并从反序列化器注入参数? 我个人更喜欢工厂定位器的明确性而不是这种情况下的约定 我想这会让你做很多工作,你可以传入Func<IDbDataReader, Func<IDbDataReader, Type>>
并让 dapper 像现在一样处理物化。 reader => reader["type"] == 1 ? typeof(Question):typeof(Answer)
相当便宜。以上是关于使用 dapper 替换成熟的 OR/M的主要内容,如果未能解决你的问题,请参考以下文章