嵌套多重映射的Dapper语法

4
    class Person
    {
        Address Addr { get; set; }
        int Age { get; set; }
    }

    class Address 
    {
        string StreetName { get; set; }
        County Cnty { get; set; }
    }

    class County
    {
         string CntyName;
         string CntyCode;
    }

这是我的存储过程,用于从数据库中填充数据。
    Create Procedure SpGetAllPersons
    As
    Select CntyName, CntyCode, StreetName, Age from Persons

我尝试编写下面的Dapper查询,但遇到了异常。
    DBConn.Query<County, Address , Person, Person>
    (DomainConstants.SpGetAllPersons,
    (cnty, address, person) =>
    {
            address.Cnty = cnty;
            person.Addr = address;
            return person;
    },
    commandType: CommandType.StoredProcedure,
    splitOn: "StreetName, Age").ToList();

我尝试使用下面的概念,但它只返回单个对象。我需要一个人员列表。
     var sql =
    @"select 
        1 as PersonId, 'bob' as Name, 
        2 as AddressId, 'abc street' as Name, 1 as PersonId,
        3 as Id, 'fred' as Name
        ";
                var personWithAddress = connection.Query<Person, Address, Extra, Tuple<Person, Address, Extra>>
                    (sql, (p, a, e) => Tuple.Create(p, a, e), splitOn: "AddressId,Id").First();

提前感谢您。

2个回答

11

感谢马克和鲍勃的帮助。我能够以其他方式解决这个问题:

    DBConn.Query(DomainConstants.SpGetAllPersons, commandType: CommandType.StoredProcedure)
    .Select(x => new Person
    {
        Addr = new Address
        {
            Cnty = new County
            {
                CntyName = x.CntyName,
                CntyCode = x.CntyCode
            },
            StreetName = x.StreetName
        },
        Age = x.Age
    }).ToList();

3
老实说,我不太理解这个代码块的意义。使用 Dapper 的美妙之处在于它应该能自动映射。 ;) - coffekid

-1

嗯,在这个例子中,您只选择了一行,因此永远不会返回多个。但是,Query<T> 返回一个 IQueryable<T>。您正在调用 .First(),因此得到一个结果并不奇怪。如果您将语句的最后部分更改为使用 .ToList(),则会获得每行一个项目的列表。


谢谢Mark。如果你看到我写的查询,它确实在结尾处有ToList()。最后,我只是提到了这个概念,我在Dapper Tests存储库中找到了它。我已经尝试使用ToList(),但我没有得到预期的对象。我得到的只是一个异常。我试图调试SQLMapper,并在反序列化类时出现错误。 - Rakshit Bakshi
1
@Rakshit 如果您提供完整的异常细节以及足够的类来理解它,我可能可以提供更多帮助。 - Marc Gravell
1
@Rakshit,说“异常”实际上一点也不有帮助。最好的方法是提供确切的消息(最好包括堆栈跟踪),逐字逐句地复制/粘贴,不要进行解释等。 - Marc Gravell
@Mark:存储过程中提供的类和表结构不足以进行测试吗?只需创建一个具有这4个列和相同3个类的表格,您就可以测试他的C#代码了... - Robert Koritnik
1
@Robert 可能吧;我睡醒后会检查一下 - Marc Gravell
抱歉 Mark,我没有提供详细的错误信息,但是我另有解决办法。 - Rakshit Bakshi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接