使用List <dictionary <string,string>&gt;使用ServiceStack ORMLite SqlList </dictionary <string,string>

时间:2013-10-15 20:14:16

标签: c# servicestack ormlite-servicestack

是否有其他人在尝试使用通用的词典列表时遇到了问题&lt; string,string&gt; (或字符串,对象)与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 深入挖掘,崩溃在这里被触发,在&#34; String Item&#34;词典的属性:

namespace ServiceStack.OrmLite
public static class PropertyInvoker

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

更新#2 使用No_Expressions编译OrmLite会以不同的方式返回propertygetter并让它流过,并且对SqlList的调用将返回正确数量的项;但是,每个词典都有0个项目。似乎它能够为每条记录创建一个新的Dictionary,但不能插入字段/列。

思想?

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

对于那些感兴趣的人,我手动添加了修复程序以执行我需要的操作。在OrmLiteReadExtensions中,我添加了一个&#34; IsDictionary&#34;使用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);
     }

0 个答案:

没有答案