映射到 PetaPoco 中的集合?

Posted

技术标签:

【中文标题】映射到 PetaPoco 中的集合?【英文标题】:Mapping to collection in PetaPoco? 【发布时间】:2012-11-18 05:10:49 【问题描述】:

有没有办法将以下内容映射到Dictionary<int,int>?它似乎为尽可能多的返回结果生成行,但它们没有值......

Sql sql = new Sql()
    .Append("SELECT Count(*) as 'Answer Count', QuestionId")
    .Append("FROM CF.Answers")
    .Append("WHERE SurveyId = @0", surveyId)
    .Append("GROUP BY QuestionId");

var result = database.Fetch<Dictionary<int,int>>(sql);

【问题讨论】:

【参考方案1】:

我会选择使用动态:

var result = database.Query<dynamic>(sql)
    .ToDictionary(d => d.QuestionId, d => d.AnswerCount);

几个注意事项:

您需要从“答案计数”列中删除空格并使用“答案计数”才能使其正常工作。 出于性能原因,我使用了Query 而不是Fetch;从理论上讲,它应该首先跳过具体化到List,而是将结果直接流式传输到Dictionary

【讨论】:

【参考方案2】:

Fetch 总是返回一个List&lt;T&gt;

Fetch&lt;T&gt;() 方法返回 List&lt;T&gt; 的事实意味着在您的代码示例中它返回

List<Dictionary<int, int>> result = ...

这可能不是您想要的,而且每本词典只包含一个项目,这完全符合您想要拥有一本词典的全部原因。据我了解,您实际上想得到的问题是:

Dictionary<int, int> result = ...

List&lt;T&gt; 上当然有扩展方法,可以让你转换为其他类型。一种这样的方法是.ToDictionary(),它可以将您的结果转换为您想要获取的字典。

最初的想法

现在我们手头的问题是我们可以使用什么类型Fetch 方法?一开始我想到了两件事:

KeyValuePair<int, int>
Tuple<int, int>

即使是好主意,但它们都不行,因为KeyValuePair 中的Key 属性没有公共设置器,第二个属性没有 PetaPoco 可以使用的无参数构造函数。

解决方案

我们在这里留下的是创建一个类似于Tuple 的自定义类型,但我们实际上可以在 PetaPoco 中使用它的功能。让我们把这个类型变成泛型,这样我们就可以很容易地用不同的类型重用它:

public class Pair<T1, T2>

    public T1 Item1  get; set; 
    public T2 Item2  get; set; 

使用这个自定义类,我们现在可以轻松获取字典:

Sql sql = new Sql()
    .Append("SELECT QuestionId as Item1, COUNT(*) as Item2")
    .Append("FROM Answers")
    .Append("WHERE SurveyId = @0", surveyId)
    .Append("GROUP BY QuestionId");

var result = database
    .Fetch<Pair<int,int>>(sql)
    .ToDictionary(i => i.Item1, i => i.Item2);

请注意,我颠倒了选择字段的顺序(并将它们设置为不同的别名),因为您不希望计数是字典键(因为它们可能会重复),而是问题 ID。所以要么你像我一样颠倒选择字段的顺序,要么为.ToDictionary()扩展方法提供正确的选择器。

【讨论】:

我尝试实现您的解决方案,但 Item1 和 Item2 的值始终为 0,因此出现重复键错误。我知道查询是正确的,并且字典的记录数为 3,但没有将值放入其中。我不确定为什么。谢谢! 如果我更改 Item1 -> QuestionId 和 Item2 -> Count 的名称,它会起作用,但这违背了使用 Dictionary 的目的。关于如何让它与 Item1 和 Item2 值一起工作的任何想法?它似乎不想映射到它们,因为它与列名不匹配。 @chobo:我能想到的唯一解释是您保留了原始 TSQL 语句语法,没有列别名,也没有更改列顺序...如果您设置列别名,那么您应该不会从查询中返回 QuestionIdCount,而是从列 Item1Item2 中返回。尤其不是Count,因为我的回答没有使用这个别名,你原来的问题也没有。 @chobo: 当你说 “如果我更改名称” 我想你是在谈论 Pair&lt;T1,T2&gt; 类中的属性名称,对吧? 哦...您在别名部分是对的,完全忽略了这一点:) 我是个白痴。非常感谢您的帮助!

以上是关于映射到 PetaPoco 中的集合?的主要内容,如果未能解决你的问题,请参考以下文章

PETAPOCO - 无效的对象名称

[转]PetaPoco入门

PetaPoco源代码学习--1.使用的Attribute介绍

PetaPoco vs NPoco

将集合('select *')映射到 MyBatis 中的字段

什么算法将集合 A 中的每个元素映射到集合 B 中的最佳匹配?