2014-10-30 88 views
17

我一直在使用dapper.net了一段时间,现在和它的一个非常好的ORM映射伟大的工程与.net动态类型,但我注意到,当从数据库中检索短小精悍的数据返回为小巧玲珑行类型是有是否可以用任何其他类型返回它的方法如System.Dynamic.ExpandoObject?小巧玲珑动态返回类型

回答

15

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

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

但是,我会支持其他类型,支持这种字典使用 - 其中ExpandoObject是其中之一。所以,是的,它可以改变这样的:

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

作品。它只需要代码支持它,并且该代码目前不存在。所以“不,但可能在未来的构建”。

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

25

当然!

按短小精悍文档中使用的查询方法,让你的dymanics:

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>,你可以随心所欲地做任何事情。

8

我有这样的问题,我通过这种方式解决了!

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

+1

为什么我们要短小精悍行明确EXPANDO对象转换,它是通过以下方法正确可转换? var rows = conn.Query (...); – 2016-04-22 05:28:46

+1

也许在下一个版本的Dapper工作正常,但在我使用的版本1.4中,这是转换后的对象没有任何属性。我从短缺问题中找到了这个解决方案。 – Behzad 2016-04-23 03:54:04