【问题标题】:Populate MVC Webgrid from DataTable从 DataTable 填充 MVC Webgrid
【发布时间】:2011-09-04 08:13:23
【问题描述】:

我正在尝试使用在后面的代码中构建的 DataTable 填充 MVC Webgrid,然后使用 AsEnumerable() 扩展方法使其可枚举。

但是,当我调用 GetHtml 方法时,输出不是我所期望的,它由两列 HasErrors 和 RowError 组成,并且没有我定义的列。

我错过了什么吗?

        DataTable table = new DataTable();
        table.Columns.Add("I/Dia");

        foreach (var item in Variations.Where(item => !table.Columns.Contains(item.CrossSectionalDiameter)))
        {
            table.Columns.Add(item.CrossSectionalDiameter);
        }

        foreach (var item in Variations)
        {
            var r = table.Rows.Add();
            r["I/Dia"] = item.InternalDiameter;
            r[item.CrossSectionalDiameter] = item.Price;
        }

        return table.AsEnumerable();

【问题讨论】:

  • 根据我在 [here][1] 找到的一篇文章,这似乎不适用于 WebGrid,因为它无法从 DataTables 中提取内容。它将一些启发式应用于动态类型,但对于所有其他类型,它从绑定类型中提取公共属性名称-值对。 RowError 和 HasError 是 DataRow 上的公共属性。不幸的是,没有一种干净的方法可以将网格绑定到动态构造的类型。臭虫:( [1]: forums.asp.net/t/1673391.aspx/1?WebGrid%20and%20DataTable

标签: asp.net-mvc-3 webgrid


【解决方案1】:

我也有类似的问题。最后根据您的评论解决一些问题。

        var result = new List<dynamic>();
        foreach (DataRow row in table.Rows)
        {
            var obj = (IDictionary<string, object>)new ExpandoObject();
            foreach (DataColumn col in table.Columns)
            {
                obj.Add(col.ColumnName, row[col.ColumnName]);
            }
            result.Add(obj);
        }
        var grid = new WebGrid(result)

【讨论】:

    【解决方案2】:

    将数据表转换为列表

        #region "Convert DataTable to List<dynamic>"
    
        public List<dynamic> ToDynamicList(DataTable dt)
        {
            List<string> cols = (dt.Columns.Cast<DataColumn>()).Select(column => column.ColumnName).ToList();
            return ToDynamicList(ToDictionary(dt), getNewObject(cols));
        }
        public List<Dictionary<string, object>> ToDictionary(DataTable dt)
        {
            var columns = dt.Columns.Cast<DataColumn>();
            var Temp = dt.AsEnumerable().Select(dataRow => columns.Select(column =>
                                 new { Column = column.ColumnName, Value = dataRow[column] })
                             .ToDictionary(data => data.Column, data => data.Value)).ToList();
            return Temp.ToList();
        }
        public List<dynamic> ToDynamicList(List<Dictionary<string, object>> list, Type TypeObj)
        {
            dynamic temp = new List<dynamic>();
            foreach (Dictionary<string, object> step in list)
            {
                object Obj = Activator.CreateInstance(TypeObj);
                PropertyInfo[] properties = Obj.GetType().GetProperties();
                Dictionary<string, object> DictList = (Dictionary<string, object>)step;
                foreach (KeyValuePair<string, object> keyValuePair in DictList)
                {
                    foreach (PropertyInfo property in properties)
                    {
                        if (property.Name == keyValuePair.Key)
                        {
                            property.SetValue(Obj, keyValuePair.Value.ToString(), null);
                            break;
                        }
                    }
                }
                temp.Add(Obj);
            }
            return temp;
        }       
        private Type getNewObject(List<string> list)
        {
            AssemblyName assemblyName = new AssemblyName();
            assemblyName.Name = "tmpAssembly";
            AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule");
            TypeBuilder typeBuilder = module.DefineType("WebgridRowCellCollection", TypeAttributes.Public);
            foreach (string step in list)
            {
                string propertyName = step;
                FieldBuilder field = typeBuilder.DefineField(propertyName, typeof(string), FieldAttributes.Public);
                PropertyBuilder property = typeBuilder.DefineProperty(propertyName, System.Reflection.PropertyAttributes.None, typeof(string), new Type[] { typeof(string) });
                MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig;
                MethodBuilder currGetPropMthdBldr = typeBuilder.DefineMethod("get_value", GetSetAttr, typeof(string), Type.EmptyTypes);
                ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
                currGetIL.Emit(OpCodes.Ldarg_0);
                currGetIL.Emit(OpCodes.Ldfld, field);
                currGetIL.Emit(OpCodes.Ret);
                MethodBuilder currSetPropMthdBldr = typeBuilder.DefineMethod("set_value", GetSetAttr, null, new Type[] { typeof(string) });
                ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
                currSetIL.Emit(OpCodes.Ldarg_0);
                currSetIL.Emit(OpCodes.Ldarg_1);
                currSetIL.Emit(OpCodes.Stfld, field);
                currSetIL.Emit(OpCodes.Ret);
                property.SetGetMethod(currGetPropMthdBldr);
                property.SetSetMethod(currSetPropMthdBldr);
            }
            Type obj = typeBuilder.CreateType();
            return obj;
        }
    
        #endregion
    

    【讨论】:

      猜你喜欢
      • 2013-10-08
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 2018-12-22
      • 1970-01-01
      相关资源
      最近更新 更多