如何使用Dapper ORM </dynamic>返回动态类型List <dynamic>

时间:2014-10-30 17:41:01

标签: c# .net orm dapper

我已经使用Dapper.net一段时间了,它是一个非常好的ORM映射器,可以很好地运行.Net动态类型。

但是我注意到当Dapper从数据库中检索数据时,它返回DapperRow类型。

是否有任何方式可以将其返回到任何其他类型,例如System.Dynamic.ExpandoObject

3 个答案:

答案 0 :(得分:39)

当然!

根据dapper文档,使用查询方法并获得你的动态:

dynamic account = conn.Query<dynamic>(@"
                    SELECT Name, Address, Country
                    FROM Account
            WHERE Id = @Id", new { Id = Id }).FirstOrDefault();
Console.WriteLine(account.Name);
Console.WriteLine(account.Address);
Console.WriteLine(account.Country);

正如您所看到的,您将获得一个动态对象,只要它们在查询语句中定义良好,您就可以访问它们的属性。

如果您省略.FirstOrDefault(),则会获得IEnumerable<dynamic>,您可以随意使用它。

答案 1 :(得分:26)

DapperRow对象旨在共享行之间的大量状态。例如,如果您获取40行,则列名称等仅存储一次。如果我们使用ExpandoObject,则需要每行配置一次。因此,使用DapperRow作为幕后实现细节是一种刻意的效率。

请注意,从dynamic API返回的对象也可以转换为IDictionary<string,object>

但是,我会支持支持此词典用法的其他类型 - 其中ExpandoObject就是其中之一。所以,是的,可以进行更改,以便:

var rows = conn.Query<ExpandoObject>(...);

的工作原理。它只需要代码来支持它,并且该代码当前不存在。所以&#34;不,但也许在未来的构建中#34;。

另请注意,您根本不需要使用DapperRow ... 预期的方案是使用通用API来实现您自己的类型。

答案 2 :(得分:10)

我有这个问题,我就这样解决了!

Query()函数返回一个动态集合,其下面实际上是Dapper.SqlMapper.DapperRow个对象类型。 Dapper.SqlMapper.DapperRow是私有的。我需要动态地向Dapper.SqlMapper.DapperRow对象添加属性,但这似乎不起作用。因此,我想将Dapper.SqlMapper.DapperRow转换为ExpandoObject

我能够像下面这样构建这个通用的帮助方法。

public class DapperHelpers
{
     public static dynamic ToExpandoObject(object value)
     {
         IDictionary<string, object> dapperRowProperties = value as IDictionary<string, object>;

         IDictionary<string, object> expando = new ExpandoObject();

         foreach (KeyValuePair<string, object> property in dapperRowProperties)
             expando.Add(property.Key, property.Value);

         return expando as ExpandoObject;
     }
}

然后你可以这样使用:

IEnumerable<ExpandoObject> result = 
           db.SqlConn.Query(sqlScript)
               .Select(x=> (ExpandoObject)ToExpandoObject(x));

参考:dapper-dot-net issues 166