3

有没有其他人在尝试使用带有 ORMLite 的SqlList功能的通用字典列表<字符串,字符串>(或字符串,对象)时遇到问题?

var data = Db.SqlList<Dictionary<string, string>>("exec my_storedproc p1,p2");

它抛出以下异常:

Incorrect number of arguments supplied for call to method 
'System.String get_Item(System.String)'

我还没有调试它的内容,但是在提取字段 defs 时它似乎在这里崩溃:

public static T ConvertTo<T>(this IDataReader dataReader)
    {
        var fieldDefs = ModelDefinition<T>.Definition.AllFieldDefinitionsArray;

注意:底层方言提供程序用于 sqlserver

更新 #1 深入挖掘,在 Dictionary 的“String Item”属性上触发了崩溃:

namespace ServiceStack.OrmLite
public static class PropertyInvoker

    public static PropertyGetterDelegate GetPropertyGetterFn(this PropertyInfo propertyInfo)
    {
    ...
    var exprCallPropertyGetFn = Expression.Call(instanceParam, getMethodInfo);

更新 #2 用 No_Expressions 编译 OrmLite 返回的属性获取器略有不同,并让它流过,并且对 SqlList 的调用返回正确的项目数;但是,每个 Dictionary 都有 0 个项目。似乎它能够为每条记录创建一个新的字典,但不能插入字段/列。

想法?

更新#3(黑客解决方案)

对于那些感兴趣的人,我手动添加了一个修复程序来做我需要的事情。在 OrmLiteReadExtensions 中,我添加了一个“IsDictionary”来配合 IsScalar 检查,然后添加了一个 ConvertToDictionary。我敢肯定,这不是最干净的解决方案,但有效。以下是片段:

public static bool IsDictionary<T>()
    {
        return typeof(IDictionary).IsAssignableFrom(typeof(T));
    }

internal static List<T> SqlList<T>(this IDbCommand dbCmd, string sql, object anonType = null)
    {
        if (anonType != null) dbCmd.SetParameters(anonType, true);
        dbCmd.CommandText = sql;

        using (var dbReader = dbCmd.ExecuteReader())
            return IsScalar<T>()
                    ? dbReader.GetFirstColumn<T>()
                    : IsDictionary<T>() 
                        ? dbReader.ConvertToDictionary<T>() 
                        : dbReader.ConvertToList<T>();
    }

public static List<T> ConvertToDictionary<T>(this IDataReader dataReader)
[...]
while (dataReader.Read())
     {
          var row = CreateInstance<T>();
          var roww = (row as Dictionary<string, object>);
          for (int f = 0; f < fields; f++)
          {
              roww.Add(dataReader.GetName(f), dataReader.GetValue(f));
          }
          to.Add(row);
     }
4

0 回答 0