使用Dapper创建匿名对象的实例

3

我正在学习Dapper技术,但是在创建匿名类型实例时遇到了困难。首先需要了解一些背景:我们有一个返回IEnumerable<T>的方法。需要注意的是,T可以是匿名类型。

IEnumerable<T> ExecuteCollection<T>(...)
{
    // Query building logic goes here.

    var statement = Something.Statement;
    var parameters = Something.Parameters;

    return _connection.Query<T>(statement, parameters);
}

这段代码对于已注册的类可以完美运行。然而,我想让它也能处理匿名类型,但是编译器抛出的问题是:

InvalidOperationException: "A parameterless default constructor or one matching signature ([signature of anonymous object]) is required for <>f__AnonymousType5`2[[System.Int16, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=XXX],[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=XXX]] materialization"

我知道问题在于匿名对象没有构造函数可用。解决方法是使用(T)Activator.CreateInstance(typeof(T), row),但变量row必须是一个object[],而不是DapperRow
每当我搜索有关此主题的信息时,每个人都说我不应该一开始就使用匿名类型。然而,我的函数必须返回匿名类型项的集合。
这是我第一次使用Dapper,我不知道我是否误解了事情。问题是:如何使用Dapper创建匿名对象实例,或者有什么替代方法可以解决此问题,使得我的方法仍然可以返回IEnumerable<T>?我正在使用.NET Core。
1个回答

3
我认为,除非我误解了你的意思,否则你只是想要调用。
connection.Query(statement, parameters);

如果没有泛型的参数,就无法完全做到您要求的,即为您提供一个整洁的行。然后您可以写如下代码:

connection.Query(statement, parameters).Select(x => new { Something = x.Something}); 

创建一个匿名对象。

或者,更复杂一些的是,你可以通过将行转换为IDictionary<string,object>来将其转换为可扩展的对象,并迭代地将属性分配给可扩展对象。


这是我目前想到的。问题是,我不能在那个new对象中硬编码属性,而且我不确定如何以编程方式迭代DapperRow和我的类型的属性,以便在ExpandoObject中重新构建新对象的结构。 - dmngrsk
我认为你可以将每一行转换为(IDictionary<string, object>)。 - gmn

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