Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams 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

My question is :
Dapper Query as IEnumerable<IDictionary<string,object>> is not null , but why after ToList then as IEnumerable<IDictionary<string,object>> is null

As I know List is extends by IEnumerable<T> so Dapper Query ToList Should be IEnumerable<IDictionay<string,object>> but result is not.

public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>

update:

And It's work if specify IDictionary<string,object> type in 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 The object inside the List is not a Dictionary, it's an anonymous object which happens to implement IDictionary, the List itself is a List of objects. In other words foreach (IDictionary<string, object> e in v) is the same as foreach (object e in v.Cast<IDictionary<string, object>()) – Charlieface Mar 21, 2021 at 11:22

The return type of Query with no generic type argument is IEnumerable<dynamic>, the actual object is a List<DapperRow>.

DapperRow happens to implement IDictionary<string, object>. Therefore:

  • In version 1 of your code you can cast the List directly to IEnumerable<IDictionary<string, object>.

  • Version 2 you are calling ToList, but because you haven't got the exact type, you end up with a call to ToList<object>. Remember, ToList always creates a new list, even when the existing object is a list already.

  • Your final version goes back to the original, but now it casts each object in the list to IDictionary<string, object>. So it is equivalent to the following code:

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

    Personally I always use actual classes with Query<MyClass> and I don't rely on dynamic or DapperRow as it can be inefficient and difficult to use.

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.

  •