将 List<object> 转换为 Dictionary<propertyname,propertyvalue>

Posted

技术标签:

【中文标题】将 List<object> 转换为 Dictionary<propertyname,propertyvalue>【英文标题】:Convert List<object> to Dictionary<propertyname,propertyvalue> 【发布时间】:2013-10-11 16:10:03 【问题描述】:

我正在尝试将数据库结果转换为属性名称、属性值类型的字典。

IEnumerable<image> results = Entity.GetAllContent<image>();

Dictionary<string, object> dict =
            results.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public).ToDictionary(
                prop => prop.Name, prop => prop.GetValue(results, null));

Entity.GetAllConent 行只是 ormlite 选择的重载。通常这将返回多个对象的通用列表(图像)。但是,当我尝试执行上述代码时,它就像是在尝试将列表或 IEnumerable 转换为字典,而不是转换基本类型。

我得到以下异常:

Parameter count mismatch.

     at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
   at Web.Controllers.HomeController.<>c__DisplayClass3.b__1(PropertyInfo prop) in d:\projects\lovelife\Web\Controllers\HomeController.cs:line 33
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
   at Web.Controllers.HomeController.Test() in d:\projects\lovelife\Web\Controllers\HomeController.cs:line 31
   at lambda_method(Closure , ControllerBase , Object[] )
   at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass42.b__41()
   at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.b__7(IAsyncResult _)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<>c__DisplayClass39.b__33()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.b__49()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.b__36(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.<>c__DisplayClass2a.b__20()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.b__22(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.<>c__DisplayClass1d.b__18(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.b__3(IAsyncResult ar)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
   at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.b__3(IAsyncResult ar)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
   at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.b__3(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.b__3(IAsyncResult ar)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
   at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

没有提供内部异常。

【问题讨论】:

我会把钱放在来自 GetValue 方法调用的参数计数不匹配上。尤其是在查看了那个调用堆栈之后。 GetParameters 提供的参数之一可能是一个列表或索引参数,GetValue 需要第二个参数为非 null 才能正确引用它。 我试图更好地理解您的最终目标:您是否尝试将 IEnumerable/List 的内容转换为字典? (字典将是 类型)....或者您是否尝试将 Ienumerable 的实际定义而不是其内容转换为字典对象...意味着您需要定义集合,以便可以根据该定义重新构建它,包括数据? 我认为是后者。我认为如下,正如我所怀疑的那样。我如何尝试是不可能的。可能我必须为我的类创建一个包装器,其中包含一个类型图像列表,并将其作为单个记录传递。都是为了 DotLiquid 的东西,但是制作它的人做了一个很小的硬编码教程,并没有给出很多线索 【参考方案1】:

我不确定这将如何工作。您有一个相同类型对象的列表 (image)。每个都将具有相同的属性(可能是 Id、Name 等)。你怎么把它们都放在一本字典里?每个人都有重复的密钥。您需要重写它以创建一个字典列表,每个元素 1 个。

var dictionaries = results.Select(x => x.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
                          .ToDictionary(prop => prop.Name, prop => prop.GetValue(x, null)))
                          .ToList();

【讨论】:

它是因为我正在尝试使用 dotliquid,但那里的开发人员没有回答任何问题,也没有提供真实案例。我必须传递一个字典,但是液体模板代码允许每个循环/。所以为此我需要一个集合。我知道你在上面说什么,这就是我想的问题,他们想要同一个类的多个实例的字典是没有意义的???? 你一定对他们想要什么感到困惑。物理上不可能有具有相同键的字典。 是的,我的想法也是如此,只是需要检查是不是我错过了一些魔法巫术或其他东西。我认为在这种情况下,我必须用 List Values 将我的 List 包装在一个持有类中,然后将该包装器作为一个请求发送。在液体中,我应该能够循环通过 classname.values,而不是 classname 打算将此标记为答案,虽然不是解决方案,但你已经确认了我的初步发现并帮助我重新思考如何解决这个问题

以上是关于将 List<object> 转换为 Dictionary<propertyname,propertyvalue>的主要内容,如果未能解决你的问题,请参考以下文章

将 List<object> 转换为 Dictionary<propertyname,propertyvalue>

将 GraphTraversal<Vertex, Map<Object, List>> 转换为 Java8 流

如何在 C# 中将 List<object> 转换为 Hashtable?

使用点分隔符将 List 转换为 String 到 Map<String, Object>

如何将map<string list<>>转换成城map<string,object>

如何将Object转换为字节数组(一个对象为List )