如何将DataTable转换为动态对象?
如何在IEnumerable
转换DataTable
?
例如,我想转换任何 DataTable
ID | Name DI | emaN --------- or --------- 1 | x 2 | x 2 | y 1 | y
在对象列表中
// list 1 (ex 1) // list 2 (ex 2) { { { ID = 1, Name = "x" } { DI = 2, emaN = "x" } { ID = 2, Name = "y" } { DI = 1, emaN = "y" } } }
所以
list1.First().ID // 1 list2.First().emaN // "x"
我该怎么做?
使用DynamicObject
怎么样:
public static class DataTableX { public static IEnumerable AsDynamicEnumerable(this DataTable table) { // Validate argument here.. return table.AsEnumerable().Select(row => new DynamicRow(row)); } private sealed class DynamicRow : DynamicObject { private readonly DataRow _row; internal DynamicRow(DataRow row) { _row = row; } // Interprets a member-access as an indexer-access on the // contained DataRow. public override bool TryGetMember(GetMemberBinder binder, out object result) { var retVal = _row.Table.Columns.Contains(binder.Name); result = retVal ? _row[binder.Name] : null; return retVal; } } }
如果您希望使动态行可写,您还可以尝试重写TrySetMember
。
用法 :
DataTable table = ... var dynamicTable = table.AsDynamicEnumerable(); var firstRowsNameField = dynamicTable.First().Name;
class Program { static void Main() { var dt = new DataTable(); dt.Columns.Add("ID", typeof(int)); dt.Columns.Add("Name", typeof(string)); dt.Rows.Add(1, "x"); dt.Rows.Add(2, "y"); List dynamicDt = dt.ToDynamic(); Console.WriteLine(dynamicDt.First().ID); Console.WriteLine(dynamicDt.First().Name); } } public static class DataTableExtensions { public static List ToDynamic(this DataTable dt) { var dynamicDt = new List (); foreach (DataRow row in dt.Rows) { dynamic dyn = new ExpandoObject(); dynamicDt.Add(dyn); foreach (DataColumn column in dt.Columns) { var dic = (IDictionary)dyn; dic[column.ColumnName] = row[column]; } } return dynamicDt; } }
以前的suneelsarraf代码仅生成运行时动态对象,其属性为字符串。 以下更新将根据DataTable列的数据类型生成每个属性。
public static class DataTableExtension { /// /// Convert a database data table to a runtime dynamic definied type collection (dynamic class' name as table name). /// /// /// /// public static List ToDynamicList(DataTable dt, string className) { return ToDynamicList(ToDictionary(dt), getNewObject(dt.Columns, className)); } private static List> ToDictionary(DataTable dt) { var columns = dt.Columns.Cast(); 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(); } private static List ToDynamicList(List> list, Type TypeObj) { dynamic temp = new List (); foreach (Dictionary step in list) { object Obj = Activator.CreateInstance(TypeObj); PropertyInfo[] properties = Obj.GetType().GetProperties(); Dictionary DictList = (Dictionary)step; foreach (KeyValuePair keyValuePair in DictList) { foreach (PropertyInfo property in properties) { if (property.Name == keyValuePair.Key) { if (keyValuePair.Value != null && keyValuePair.Value.GetType() != typeof(System.DBNull)) { if (keyValuePair.Value.GetType() == typeof(System.Guid)) { property.SetValue(Obj, keyValuePair.Value, null); } else { property.SetValue(Obj, keyValuePair.Value, null); } } break; } } } temp.Add(Obj); } return temp; } private static Type getNewObject(DataColumnCollection columns, string className) { AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "YourAssembly"; System.Reflection.Emit.AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder module = assemblyBuilder.DefineDynamicModule("YourDynamicModule"); TypeBuilder typeBuilder = module.DefineType(className, TypeAttributes.Public); foreach (DataColumn column in columns) { string propertyName = column.ColumnName; FieldBuilder field = typeBuilder.DefineField(propertyName, column.DataType, FieldAttributes.Public); PropertyBuilder property = typeBuilder.DefineProperty(propertyName, System.Reflection.PropertyAttributes.None, column.DataType, new Type[] { column.DataType }); MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig; MethodBuilder currGetPropMthdBldr = typeBuilder.DefineMethod("get_value", GetSetAttr, column.DataType, new Type[] { column.DataType }); // 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[] { column.DataType }); 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; } }
有些ORM可以直接从DB读取到dynamic ExpandoObject
。 例如petapoco (在这里阅读示例 )
或者你可以尝试类似的东西:
var dt = new DataTable(); var dns = new List(); foreach (var item in dt.AsEnumerable()) { // Expando objects are IDictionary IDictionary dn = new ExpandoObject(); foreach (var column in dt.Columns.Cast()) { dn[column.ColumnName] = item[column]; } dns.Add(dn); } // Now you can do something like dns[0].MyColumnName // or recast to IDictionary and do // something like casted["MyColumnName"]
尝试
var MyResult = from x in MyDataTable select new { ID = x["ID"], Name = x["Name"] }.ToList ();
将数据表转换为列表
#region "Convert DataTable to List" public List ToDynamicList(DataTable dt) { List cols = (dt.Columns.Cast()).Select(column => column.ColumnName).ToList(); return ToDynamicList(ToDictionary(dt), getNewObject(cols)); } public List> ToDictionary(DataTable dt) { var columns = dt.Columns.Cast (); 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 ToDynamicList(List> list, Type TypeObj) { dynamic temp = new List (); foreach (Dictionary step in list) { object Obj = Activator.CreateInstance(TypeObj); PropertyInfo[] properties = Obj.GetType().GetProperties(); Dictionary DictList = (Dictionary)step; foreach (KeyValuePair 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 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
你可以使用这样的扩展:
using System; using System.Collections.Generic; using System.Data; using System.Dynamic; public static class DataTableExtensions { public static IEnumerable AsDynamicEnumerable(this DataTable table) { if (table == null) { yield break; } foreach (DataRow row in table.Rows) { IDictionary dRow = new ExpandoObject(); foreach (DataColumn column in table.Columns) { var value = row[column.ColumnName]; dRow[column.ColumnName] = Convert.IsDBNull(value) ? null : value; } yield return dRow; } } }
用法:
var dataTable = GetDataTableFromSomewhere(); var dynamicTable = dataTable.AsDynamicEnumerable(); var firstRowIDColumn = dynamicTable.First().ID; var lastRowIDColumn = dynamicTable.Last()["ID"];
但如果可能的话,我更喜欢IDataReader方法。
上述就是C#学习教程:如何将DataTable转换为动态对象?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/996742.html