带有postgresql错误的Dapper(序列包含多个元素)

时间:2016-06-26 06:15:35

标签: c# sql postgresql dapper

当我使用存储过程对Postgresql DB运行集成测试时出现此错误。

Result Message: System.InvalidOperationException : Sequence contains more than one element

这是repo文件:

  public card_view SelectView(int card_id)
        {
            using (var connection = new NpgsqlConnection(ConfigurationSettings.GetConnectionString()))
            {
                var p = new DynamicParameters();
                p.Add("@card_id", card_id);

                using (var multi = connection.QueryMultiple("f_card_select_view", p, commandType: CommandType.StoredProcedure))
                {
                    card_view view = multi.Read<card_view>().Single();
                    view.Categories = multi.Read<category>().ToList();
                    view.Modifiers = multi.Read<card_modifier_view>().ToList();

                    return view;
                }
            }
        }

卡片测试文件:

   [Test]
    public void SelectViewTest()
    {
        var repo = new CardRepository();
        var result = repo.SelectView(31);  // witch

        Assert.AreEqual(2, result.Categories.Count);
        Assert.AreEqual(2, result.Modifiers.Count);
    }

Cardview文件:

public class card_view
    {
        public int card_id { get; set; }
        public int cardset_id { get; set; }
        public string cardset_title { get; set; }
        public string image_path { get; set; }
        public string cardset_name { get; set; }
        public int card_cost { get; set; }

        public List<card_modifier_view> Modifiers { get; set; }
        public List<category> Categories { get; set; }
    }

cardmodifierview文件:

public class card_modifier_view
    {
        public int card_modifier_id { get; set; }
        public int card_id { get; set; }
        public int modifier_type_id { get; set; }
        public int? modifier_value { get; set; }
        public string instruction_text { get; set; }
        public string modifier_type_name { get; set; }
    }

数据库功能(原始SQL是T-SQL,我已尽力将其翻译成postgres的常规SQL。)

CREATE FUNCTION f_card_select_view (card_id int)
RETURNS TABLE(card_id bigint, modifier_type_id integer, 
instruction_text integer, modifier_type_name integer, card_modifier character varying, modifier_type character varying)
AS $$
SELECT card_id,cardset.cardset_id,card_title,image_path,card_cost,cardset_name
FROM card 
INNER JOIN cardset ON card.cardset_id = cardset.cardset_id
WHERE card_id = @card_id;
SELECT  card.category_id,category_name
FROM category card
INNER JOIN card_category ON card.category_id = card_category.category_id
WHERE card_category.card_id = @card_id;
SELECT f_card_modifier_selectby_card_id (@card_id);
$$ LANGUAGE sql;

这是f_card_modifier_selectby_card_id:

CREATE FUNCTION f_card_modifier_selectby_card_id(card_id int)
RETURNS TABLE(
card_id bigint,
modifier_type_id int,
instruction_text int,
modifier_type_name int,
card_modifier varchar,
modifier_type varchar
)
AS $$

SELECT
card_modifier_id,
card_id,
card_modifier.modifier_type_id,
modifier_value,
instruction_text,
modifier_type_name
FROM card_modifier INNER JOIN modifier_type ON card_modifier.modifier_type_id = modifier_type.modifier_type_id
WHERE card_id = card_id

$$ LANGUAGE sql;

2 个答案:

答案 0 :(得分:1)

如果错误为Sequence contains more than one element,则问题在于您的第一个查询(.Single() 返回多行 。我无法告诉你为什么会这样,但你需要尝试运行:

SELECT card_id,cardset.cardset_id,card_title,image_path,card_cost,cardset_name
FROM card 
INNER JOIN cardset ON card.cardset_id = cardset.cardset_id
WHERE card_id = @card_id;

(在您的SQL工具包中使用您期望的@card_id)来查看会发生什么。或者更好:通过以下方式调用存储过程本身 -

EXEC f_card_select_view {your id here}

答案 1 :(得分:1)

看起来你的语句会带回一个包含card_view或0的多个记录的连接。

在其他框架中,您当然可以使用SingleOrDefault()来允许0条记录。请注意,对于多个记录,这仍然会出错。

如果它获得了多条记录,你需要确定这是否正确,并将其重新编写成一个类似于.ToList()的集合,或更正数据库中的数据以及可能的密钥。