【问题标题】:Dapper multiple objects from one row从一行中提取多个对象
【发布时间】:2013-07-19 20:35:49
【问题描述】:

我有一行来自数据库

select "John" Name, 
       "Male" Gender,
       20 Age,
       "Rex" PetName,
       "Male" PetGender,
       5 PetAge
       // ... many more ...

使用 Dapper,我想将此行分成两个对象:

class Person
{
    public string Name { get; set; }
    public string Gender { get; set; }
    public int Age { get; set; }
    // ... many more ...
}    
class Pet
{
    public string PetName { get; set; }
    public string PetGender { get; set; }
    public int PetAge { get; set; }
    // ... many more ...
}

注意:这里没有层次关系,我只是试图将一个数据库行映射到两个(或更多)对象。

如何使用 dapper 做到这一点?

  • 我知道我可以通过返回动态并手动映射每个对象来做到这一点,这很痛苦,因为在我的场景中我们有大量的列。我宁愿不这样做。 (不,它不能被重新设计为需要更少的列。)

我尝试过的:

  • 我查看了QueryMultiple<Person,Pet>,但它假定我正在运行多个查询。在我的现实生活场景中,这是一个非常昂贵的查询,我只想运行一次。
  • 我也考虑过返回Query<Person,Pet,Tuple<Person,Pet>>,但这需要Id 列,这里没有层次关系或Ids。我只想取一行并将其映射到多列。

【问题讨论】:

    标签: c# dapper


    【解决方案1】:

    您已经非常接近使用 Query 方法的解决方案了。如果您没有Id 列,则可以提供splitOn 参数:

    connection.Query<Person, Pet, Tuple<Person, Pet>>(sql, 
        (person, pet) => Tuple.Create(person, pet), splitOn: "PetName");
    

    【讨论】:

    • 我错过了什么吗?即使我提供splitOn,我仍然得到ArgumentException: When using the multi-mapping APIs ensure you set the splitOn param if you have keys other than Id. Parameter name: splitOn
    • 这很奇怪。您可能需要向我们展示确切的 sql 查询和代码。不太可能,但也许您的 splitOn 字段也存在于第一种类型中,并且您的意思是将其包含在第二种类型中,是否有机会?
    • 你说得对,当我将它与这个玩具场景一起使用时,它工作得很好。我必须深入挖掘并找出我的东西在我的真实代码中哪里出了问题。
    • 逻辑真的很简单。它按顺序查看列。在您的示例查询中,如果您说splitOn="PetName",它将使用前 3 列来构建 Person,其余列来构建 Pet。如果 Person 有更多不在前 3 列中的属性/字段,则这些道具将保持其默认值(例如 null)。
    • 我认为最好的文档是Tests.cs
    猜你喜欢
    • 1970-01-01
    • 2012-04-23
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 2022-01-22
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多