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> 一起使用,我不依赖 dynamicDapperRow,因为它们可能效率低下并且难用。