8

有没有办法将以下内容映射到 a 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);
4

2 回答 2

15

Fetch 总是返回一个List<T>

Fetch<T>()方法返回 a的事实List<T>意味着在您的代码示例中它返回

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

这可能不是您想要的,而且每本字典只会包含一个项目,这比您首先想要拥有一本字典的全部原因更胜一筹。据我了解,您实际上想要得到的问题是:

Dictionary<int, int> result = ...

当然,还有一些扩展方法List<T>可以让您将其转换为其他类型。一种这样的方法是.ToDictionary()可以将您的结果转换为您想要获取的字典。

第一个想法

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

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

尽管好主意,但它们都不行,因为Key属性 inKeyValuePair没有公共设置器,而第二个属性没有 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()扩展方法提供正确的选择器。

于 2012-11-30T13:20:45.090 回答
1

我会选择使用动态:

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

几点注意事项:

  • 您需要从“答案计数”列中删除空间并使用“答案计数”才能使其正常工作。
  • 出于性能原因,我使用Query而不是;Fetch从理论上讲,它应该跳过具体化到List第一个,而是将结果直接流式传输到Dictionary.
于 2014-03-09T22:05:32.510 回答