首页 > 解决方案 > Dapper 查询 ToList 为 IEnumerable> 结果为空

问题描述

我的代码

    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 之后然后 asIEnumerable<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           
            }
        }

标签: .netlinqdapper

解决方案


Query没有泛型类型参数的返回类型是IEnumerable<dynamic>,实际对象是 a List<DapperRow>

DapperRow恰好执行IDictionary<string, object>。所以:

  • 在您的代码版本 1 中,您可以将其List直接转换为IEnumerable<IDictionary<string, object>.

  • 您正在调用版本 2 ToList,但由于您没有确切的类型,因此您最终会调用ToList<object>. 请记住,ToList 始终创建一个新列表,即使现有对象已经是一个列表。

  • 您的最终版本回到原始版本,但现在它将列表中的每个对象转换为IDictionary<string, object>. 所以它相当于下面的代码:

foreach (var e in v.Cast<IDictionary<string, object>())
{

就我个人而言,我总是使用实际的类,Query<MyClass>并且我不依赖它dynamicDapperRow因为它可能效率低下且难以使用。


推荐阅读