Dapper Query ToList as IEnumerable<IDictionary<string,object>> 结果为空
Dapper Query ToList as IEnumerable<IDictionary<string,object>> result is null
我的代码
using (var connection = new SQLiteConnection("Data Source=:memory:"))
{
{
var v = connection.Query(@"select 1 A,2 B ");
var cV = v as IEnumerable<IDictionary<string,object>>;
Console.WriteLine(v.GetType().FullName); // result : System.Collections.Generic.List`1[[Dapper.SqlMapper+DapperRow, Dapper, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]]
Console.WriteLine(cV); // result : A=1,B=2
}
{
var v = connection.Query(@"select 1 A,2 B ").ToList();
var cV = v as IEnumerable<IDictionary<string, object>>;
Console.WriteLine(v.GetType().FullName); // result : System.Collections.Generic.List`1[[System.Object, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
Console.WriteLine(cV); // result : null
}
}
我的问题是:
Dapper Query as IEnumerable<IDictionary<string,object>>
is not null
,但为什么在 ToList 之后又是 IEnumerable<IDictionary<string,object>>
is null
据我所知,List 由 IEnumerable<T>
扩展,所以 Dapper Query ToList 应该是 IEnumerable<IDictionay<string,object>>
但结果不是。
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>
更新:
如果指定 IDictionary<string,object>
输入 foreach
就可以了
{
var v = connection.Query(@"select 1 A,2 B ").ToList();
foreach (IDictionary<string, object> e in v)
{
Console.WriteLine(v.GetType().FullName); // result : System.Collections.Generic.List`1[[System.Object, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
Console.WriteLine(e); // result : A=1,B=2
}
}
没有泛型参数的Query
的return类型是IEnumerable<dynamic>
,实际对象是List<DapperRow>
.
DapperRow
恰好实现了 IDictionary<string, object>
。因此:
在代码的版本 1 中,您可以将 List
直接转换为 IEnumerable<IDictionary<string, object>
。
您正在调用 ToList
的版本 2,但是因为您没有获得确切的类型,所以您最终调用了 ToList<object>
。请记住,ToList
总是 创建一个新列表,即使现有对象已经是一个列表。
您的最终版本返回到原始版本,但现在它将列表中的每个对象转换为 IDictionary<string, object>
。所以相当于下面的代码:
foreach (var e in v.Cast<IDictionary<string, object>())
{
就我个人而言,我总是将实际的 类 与 Query<MyClass>
一起使用,我不依赖 dynamic
或 DapperRow
,因为它们可能效率低下并且难用。
我的代码
using (var connection = new SQLiteConnection("Data Source=:memory:"))
{
{
var v = connection.Query(@"select 1 A,2 B ");
var cV = v as IEnumerable<IDictionary<string,object>>;
Console.WriteLine(v.GetType().FullName); // result : System.Collections.Generic.List`1[[Dapper.SqlMapper+DapperRow, Dapper, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]]
Console.WriteLine(cV); // result : A=1,B=2
}
{
var v = connection.Query(@"select 1 A,2 B ").ToList();
var cV = v as IEnumerable<IDictionary<string, object>>;
Console.WriteLine(v.GetType().FullName); // result : System.Collections.Generic.List`1[[System.Object, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
Console.WriteLine(cV); // result : null
}
}
我的问题是:
Dapper Query as IEnumerable<IDictionary<string,object>>
is not null
,但为什么在 ToList 之后又是 IEnumerable<IDictionary<string,object>>
is null
据我所知,List 由 IEnumerable<T>
扩展,所以 Dapper Query ToList 应该是 IEnumerable<IDictionay<string,object>>
但结果不是。
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>
更新:
如果指定 IDictionary<string,object>
输入 foreach
{
var v = connection.Query(@"select 1 A,2 B ").ToList();
foreach (IDictionary<string, object> e in v)
{
Console.WriteLine(v.GetType().FullName); // result : System.Collections.Generic.List`1[[System.Object, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
Console.WriteLine(e); // result : A=1,B=2
}
}
没有泛型参数的Query
的return类型是IEnumerable<dynamic>
,实际对象是List<DapperRow>
.
DapperRow
恰好实现了 IDictionary<string, object>
。因此:
在代码的版本 1 中,您可以将
List
直接转换为IEnumerable<IDictionary<string, object>
。您正在调用
ToList
的版本 2,但是因为您没有获得确切的类型,所以您最终调用了ToList<object>
。请记住,ToList
总是 创建一个新列表,即使现有对象已经是一个列表。您的最终版本返回到原始版本,但现在它将列表中的每个对象转换为
IDictionary<string, object>
。所以相当于下面的代码:
foreach (var e in v.Cast<IDictionary<string, object>())
{
就我个人而言,我总是将实际的 类 与 Query<MyClass>
一起使用,我不依赖 dynamic
或 DapperRow
,因为它们可能效率低下并且难用。