我已经使用Dapper.net一段时间了,它是一个非常好的ORM映射器,可以很好地运行.Net动态类型。
但是我注意到当Dapper从数据库中检索数据时,它返回DapperRow
类型。
是否有任何方式可以将其返回到任何其他类型,例如System.Dynamic.ExpandoObject
?
答案 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));