瀏覽代碼

datatable

懒得勤快 6 年之前
父節點
當前提交
9090d23968

+ 70 - 0
Masuit.Tools.Core/Database/DataTableBuilder.cs

@@ -0,0 +1,70 @@
+using System;
+using System.Data;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace Masuit.Tools.Core.Database
+{
+    internal class DataTableBuilder<T>
+    {
+        private static readonly MethodInfo GetValueMethod = typeof(DataRow).GetMethod("get_Item", new[]
+        {
+            typeof(int)
+        });
+
+        private static readonly MethodInfo IsDbNullMethod = typeof(DataRow).GetMethod("IsNull", new[]
+        {
+            typeof(int)
+        });
+
+        private delegate T Load(DataRow dataRecord);
+
+        private Load _handler;
+
+        private DataTableBuilder()
+        {
+        }
+
+        public T Build(DataRow dataRecord)
+        {
+            return _handler(dataRecord);
+        }
+
+        public static DataTableBuilder<T> CreateBuilder(DataRow dataRecord)
+        {
+            DataTableBuilder<T> dynamicBuilder = new DataTableBuilder<T>();
+            DynamicMethod method = new DynamicMethod("DynamicCreateEntity", typeof(T), new Type[]
+            {
+                typeof(DataRow)
+            }, typeof(T), true);
+            ILGenerator generator = method.GetILGenerator();
+            LocalBuilder result = generator.DeclareLocal(typeof(T));
+            generator.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));
+            generator.Emit(OpCodes.Stloc, result);
+            for (int i = 0; i < dataRecord.ItemArray.Length; i++)
+            {
+                PropertyInfo propertyInfo = typeof(T).GetProperty(dataRecord.Table.Columns[i].ColumnName);
+                Label endIfLabel = generator.DefineLabel();
+                if (propertyInfo != null && propertyInfo.GetSetMethod() != null)
+                {
+                    generator.Emit(OpCodes.Ldarg_0);
+                    generator.Emit(OpCodes.Ldc_I4, i);
+                    generator.Emit(OpCodes.Callvirt, IsDbNullMethod);
+                    generator.Emit(OpCodes.Brtrue, endIfLabel);
+                    generator.Emit(OpCodes.Ldloc, result);
+                    generator.Emit(OpCodes.Ldarg_0);
+                    generator.Emit(OpCodes.Ldc_I4, i);
+                    generator.Emit(OpCodes.Callvirt, GetValueMethod);
+                    generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
+                    generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());
+                    generator.MarkLabel(endIfLabel);
+                }
+            }
+
+            generator.Emit(OpCodes.Ldloc, result);
+            generator.Emit(OpCodes.Ret);
+            dynamicBuilder._handler = (Load)method.CreateDelegate(typeof(Load));
+            return dynamicBuilder;
+        }
+    }
+}

+ 15 - 115
Masuit.Tools.Core/Database/DataTableHelper.cs

@@ -43,88 +43,29 @@ namespace Masuit.Tools.Core.Database
         }
 
         /// <summary>
-        /// DataTable转换成实体列表
+        /// datatable转List
         /// </summary>
-        /// <typeparam name="T">实体 T </typeparam>
-        /// <param name="table">datatable</param>
-        /// <returns>强类型的数据集合</returns>
-        public static IList<T> DataTableToList<T>(this DataTable table) where T : class
-        {
-            if (!HasRows(table))
-            {
-                return new List<T>();
-            }
-
-            IList<T> list = new List<T>();
-            foreach (DataRow dr in table.Rows)
-            {
-                var model = Activator.CreateInstance<T>();
-
-                foreach (DataColumn dc in dr.Table.Columns)
-                {
-                    object drValue = dr[dc.ColumnName];
-                    PropertyInfo pi = model.GetType().GetProperty(dc.ColumnName);
-
-                    if (pi != null && pi.CanWrite && (drValue != null && !Convert.IsDBNull(drValue)))
-                    {
-                        pi.SetValue(model, drValue, null);
-                    }
-                }
-
-                list.Add(model);
-            }
-
-            return list;
-        }
-
-        /// <summary>
-        /// 实体列表转换成DataTable
-        /// </summary>
-        /// <typeparam name="T">实体</typeparam>
-        /// <param name="list"> 实体列表</param>
-        /// <returns>映射为数据表</returns>
-        /// <exception cref="OverflowException">The array is multidimensional and contains more than <see cref="F:System.Int32.MaxValue" /> elements.</exception>
-        public static DataTable ListToDataTable<T>(this IList<T> list) where T : class
+        /// <typeparam name="T"></typeparam>
+        /// <param name="dt"></param>
+        /// <returns></returns>
+        public static List<T> ToList<T>(this DataTable dt) where T : class, new()
         {
-            if (list == null || list.Count <= 0)
+            List<T> list = new List<T>();
+            using (dt)
             {
-                return null;
-            }
-
-            var dt = new DataTable(typeof(T).Name);
-            PropertyInfo[] myPropertyInfo = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
-            int length = myPropertyInfo.Length;
-            bool createColumn = true;
-            foreach (T t in list)
-            {
-                if (t == null)
+                if (dt == null || dt.Rows.Count == 0)
                 {
-                    continue;
+                    return list;
                 }
 
-                var row = dt.NewRow();
-                for (int i = 0; i < length; i++)
+                DataTableBuilder<T> eblist = DataTableBuilder<T>.CreateBuilder(dt.Rows[0]);
+                foreach (DataRow info in dt.Rows)
                 {
-                    PropertyInfo pi = myPropertyInfo[i];
-                    string name = pi.Name;
-                    if (createColumn)
-                    {
-                        var column = new DataColumn(name, pi.PropertyType);
-                        dt.Columns.Add(column);
-                    }
-
-                    row[name] = pi.GetValue(t, null);
+                    list.Add(eblist.Build(info));
                 }
 
-                if (createColumn)
-                {
-                    createColumn = false;
-                }
-
-                dt.Rows.Add(row);
+                return list;
             }
-
-            return dt;
         }
 
         /// <summary>
@@ -354,53 +295,12 @@ namespace Masuit.Tools.Core.Database
 
             DataTable dt = rows[0].Table.Clone();
             dt.DefaultView.Sort = rows[0].Table.DefaultView.Sort;
-            for (int i = 0; i < rows.Length; i++)
+            foreach (var t in rows)
             {
-                dt.LoadDataRow(rows[i].ItemArray, true);
+                dt.LoadDataRow(t.ItemArray, true);
             }
 
             return dt;
         }
-
-        /// <summary>
-        /// 排序表的视图
-        /// </summary>
-        /// <param name="dt">原内存表</param>
-        /// <param name="sorts">排序方式</param>
-        /// <returns>排序后的内存表</returns>
-        public static DataTable SortedTable(this DataTable dt, params string[] sorts)
-        {
-            if (dt.Rows.Count > 0)
-            {
-                string tmp = "";
-                foreach (var t in sorts)
-                {
-                    tmp += t + ",";
-                }
-
-                dt.DefaultView.Sort = tmp.TrimEnd(',');
-            }
-
-            return dt;
-        }
-
-        /// <summary>
-        /// 根据条件过滤表的内容
-        /// </summary>
-        /// <param name="dt">原内存表</param>
-        /// <param name="condition">过滤条件</param>
-        /// <returns>过滤后的内存表</returns>
-        public static DataTable FilterDataTable(this DataTable dt, string condition)
-        {
-            if (condition.Trim().Length == 0)
-            {
-                return dt;
-            }
-
-            var newdt = dt.Clone();
-            DataRow[] dr = dt.Select(condition);
-            dr.ForEach(t => newdt.ImportRow(t));
-            return newdt;
-        }
     }
 }

+ 1 - 1
Masuit.Tools.Core/Masuit.Tools.Core.csproj

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <TargetFramework>netcoreapp2.1</TargetFramework>
-    <Version>2.2.4.6</Version>
+    <Version>2.2.5</Version>
     <Authors>懒得勤快</Authors>
     <Company>masuit.com</Company>
     <Description>包含一些常用的操作类,大都是静态类,加密解密,反射操作,硬件信息,字符串扩展方法,日期时间扩展操作,大文件拷贝,图像裁剪,html处理,验证码、NoSql等常用封装。

+ 5 - 30
Masuit.Tools.Core/Masuit.Tools.Core.xml

@@ -514,22 +514,13 @@
             <param name="dt">DataTable</param>
             <returns>是否有数据行</returns>
         </member>
-        <member name="M:Masuit.Tools.Core.Database.DataTableHelper.DataTableToList``1(System.Data.DataTable)">
+        <member name="M:Masuit.Tools.Core.Database.DataTableHelper.ToList``1(System.Data.DataTable)">
             <summary>
-            DataTable转换成实体列表
+            datatable转List
             </summary>
-            <typeparam name="T">实体 T </typeparam>
-            <param name="table">datatable</param>
-            <returns>强类型的数据集合</returns>
-        </member>
-        <member name="M:Masuit.Tools.Core.Database.DataTableHelper.ListToDataTable``1(System.Collections.Generic.IList{``0})">
-            <summary>
-            实体列表转换成DataTable
-            </summary>
-            <typeparam name="T">实体</typeparam>
-            <param name="list"> 实体列表</param>
-            <returns>映射为数据表</returns>
-            <exception cref="T:System.OverflowException">The array is multidimensional and contains more than <see cref="F:System.Int32.MaxValue" /> elements.</exception>
+            <typeparam name="T"></typeparam>
+            <param name="dt"></param>
+            <returns></returns>
         </member>
         <member name="M:Masuit.Tools.Core.Database.DataTableHelper.ToDataTable``1(System.Collections.Generic.IList{``0})">
             <summary>
@@ -587,22 +578,6 @@
             <param name="rows">行数组</param>
             <returns>将内存行组装成内存表</returns>
         </member>
-        <member name="M:Masuit.Tools.Core.Database.DataTableHelper.SortedTable(System.Data.DataTable,System.String[])">
-            <summary>
-            排序表的视图
-            </summary>
-            <param name="dt">原内存表</param>
-            <param name="sorts">排序方式</param>
-            <returns>排序后的内存表</returns>
-        </member>
-        <member name="M:Masuit.Tools.Core.Database.DataTableHelper.FilterDataTable(System.Data.DataTable,System.String)">
-            <summary>
-            根据条件过滤表的内容
-            </summary>
-            <param name="dt">原内存表</param>
-            <param name="condition">过滤条件</param>
-            <returns>过滤后的内存表</returns>
-        </member>
         <member name="T:Masuit.Tools.Core.Linq.LinqExtension">
             <summary>
             linq扩展类

+ 70 - 0
Masuit.Tools/Database/DataTableBuilder.cs

@@ -0,0 +1,70 @@
+using System;
+using System.Data;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace Masuit.Tools.Database
+{
+    internal class DataTableBuilder<T>
+    {
+        private static readonly MethodInfo GetValueMethod = typeof(DataRow).GetMethod("get_Item", new[]
+        {
+            typeof(int)
+        });
+
+        private static readonly MethodInfo IsDbNullMethod = typeof(DataRow).GetMethod("IsNull", new[]
+        {
+            typeof(int)
+        });
+
+        private delegate T Load(DataRow dataRecord);
+
+        private Load _handler;
+
+        private DataTableBuilder()
+        {
+        }
+
+        public T Build(DataRow dataRecord)
+        {
+            return _handler(dataRecord);
+        }
+
+        public static DataTableBuilder<T> CreateBuilder(DataRow dataRecord)
+        {
+            DataTableBuilder<T> dynamicBuilder = new DataTableBuilder<T>();
+            DynamicMethod method = new DynamicMethod("DynamicCreateEntity", typeof(T), new Type[]
+            {
+                typeof(DataRow)
+            }, typeof(T), true);
+            ILGenerator generator = method.GetILGenerator();
+            LocalBuilder result = generator.DeclareLocal(typeof(T));
+            generator.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));
+            generator.Emit(OpCodes.Stloc, result);
+            for (int i = 0; i < dataRecord.ItemArray.Length; i++)
+            {
+                PropertyInfo propertyInfo = typeof(T).GetProperty(dataRecord.Table.Columns[i].ColumnName);
+                Label endIfLabel = generator.DefineLabel();
+                if (propertyInfo != null && propertyInfo.GetSetMethod() != null)
+                {
+                    generator.Emit(OpCodes.Ldarg_0);
+                    generator.Emit(OpCodes.Ldc_I4, i);
+                    generator.Emit(OpCodes.Callvirt, IsDbNullMethod);
+                    generator.Emit(OpCodes.Brtrue, endIfLabel);
+                    generator.Emit(OpCodes.Ldloc, result);
+                    generator.Emit(OpCodes.Ldarg_0);
+                    generator.Emit(OpCodes.Ldc_I4, i);
+                    generator.Emit(OpCodes.Callvirt, GetValueMethod);
+                    generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
+                    generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());
+                    generator.MarkLabel(endIfLabel);
+                }
+            }
+
+            generator.Emit(OpCodes.Ldloc, result);
+            generator.Emit(OpCodes.Ret);
+            dynamicBuilder._handler = (Load)method.CreateDelegate(typeof(Load));
+            return dynamicBuilder;
+        }
+    }
+}

+ 15 - 115
Masuit.Tools/Database/DataTableHelper.cs

@@ -43,88 +43,29 @@ namespace Masuit.Tools.Database
         }
 
         /// <summary>
-        /// DataTable转换成实体列表
+        /// datatable转List
         /// </summary>
-        /// <typeparam name="T">实体 T </typeparam>
-        /// <param name="table">datatable</param>
-        /// <returns>强类型的数据集合</returns>
-        public static IList<T> DataTableToList<T>(this DataTable table) where T : class
-        {
-            if (!HasRows(table))
-            {
-                return new List<T>();
-            }
-
-            IList<T> list = new List<T>();
-            foreach (DataRow dr in table.Rows)
-            {
-                var model = Activator.CreateInstance<T>();
-
-                foreach (DataColumn dc in dr.Table.Columns)
-                {
-                    object drValue = dr[dc.ColumnName];
-                    PropertyInfo pi = model.GetType().GetProperty(dc.ColumnName);
-
-                    if (pi != null && pi.CanWrite && (drValue != null && !Convert.IsDBNull(drValue)))
-                    {
-                        pi.SetValue(model, drValue, null);
-                    }
-                }
-
-                list.Add(model);
-            }
-
-            return list;
-        }
-
-        /// <summary>
-        /// 实体列表转换成DataTable
-        /// </summary>
-        /// <typeparam name="T">实体</typeparam>
-        /// <param name="list"> 实体列表</param>
-        /// <returns>映射为数据表</returns>
-        /// <exception cref="OverflowException">The array is multidimensional and contains more than <see cref="F:System.Int32.MaxValue" /> elements.</exception>
-        public static DataTable ListToDataTable<T>(this IList<T> list) where T : class
+        /// <typeparam name="T"></typeparam>
+        /// <param name="dt"></param>
+        /// <returns></returns>
+        public static List<T> ToList<T>(this DataTable dt) where T : class, new()
         {
-            if (list == null || list.Count <= 0)
+            List<T> list = new List<T>();
+            using (dt)
             {
-                return null;
-            }
-
-            var dt = new DataTable(typeof(T).Name);
-            PropertyInfo[] myPropertyInfo = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
-            int length = myPropertyInfo.Length;
-            bool createColumn = true;
-            foreach (T t in list)
-            {
-                if (t == null)
+                if (dt == null || dt.Rows.Count == 0)
                 {
-                    continue;
+                    return list;
                 }
 
-                var row = dt.NewRow();
-                for (int i = 0; i < length; i++)
+                DataTableBuilder<T> eblist = DataTableBuilder<T>.CreateBuilder(dt.Rows[0]);
+                foreach (DataRow info in dt.Rows)
                 {
-                    PropertyInfo pi = myPropertyInfo[i];
-                    string name = pi.Name;
-                    if (createColumn)
-                    {
-                        var column = new DataColumn(name, pi.PropertyType);
-                        dt.Columns.Add(column);
-                    }
-
-                    row[name] = pi.GetValue(t, null);
+                    list.Add(eblist.Build(info));
                 }
 
-                if (createColumn)
-                {
-                    createColumn = false;
-                }
-
-                dt.Rows.Add(row);
+                return list;
             }
-
-            return dt;
         }
 
         /// <summary>
@@ -354,53 +295,12 @@ namespace Masuit.Tools.Database
 
             DataTable dt = rows[0].Table.Clone();
             dt.DefaultView.Sort = rows[0].Table.DefaultView.Sort;
-            for (int i = 0; i < rows.Length; i++)
+            foreach (var t in rows)
             {
-                dt.LoadDataRow(rows[i].ItemArray, true);
+                dt.LoadDataRow(t.ItemArray, true);
             }
 
             return dt;
         }
-
-        /// <summary>
-        /// 排序表的视图
-        /// </summary>
-        /// <param name="dt">原内存表</param>
-        /// <param name="sorts">排序方式</param>
-        /// <returns>排序后的内存表</returns>
-        public static DataTable SortedTable(this DataTable dt, params string[] sorts)
-        {
-            if (dt.Rows.Count > 0)
-            {
-                string tmp = "";
-                for (int i = 0; i < sorts.Length; i++)
-                {
-                    tmp += sorts[i] + ",";
-                }
-
-                dt.DefaultView.Sort = tmp.TrimEnd(',');
-            }
-
-            return dt;
-        }
-
-        /// <summary>
-        /// 根据条件过滤表的内容
-        /// </summary>
-        /// <param name="dt">原内存表</param>
-        /// <param name="condition">过滤条件</param>
-        /// <returns>过滤后的内存表</returns>
-        public static DataTable FilterDataTable(this DataTable dt, string condition)
-        {
-            if (condition.Trim().Length == 0)
-            {
-                return dt;
-            }
-
-            var newdt = dt.Clone();
-            DataRow[] dr = dt.Select(condition);
-            dr.ForEach(t => newdt.ImportRow(t));
-            return newdt;
-        }
     }
 }

+ 1 - 0
Masuit.Tools/Masuit.Tools.csproj

@@ -91,6 +91,7 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Database\DataTableBuilder.cs" />
     <Compile Include="Database\DataTableHelper.cs" />
     <Compile Include="DateTimeExt\ChineseCalendar.cs" />
     <Compile Include="Database\DataExt.cs" />

+ 2 - 2
Masuit.Tools/Properties/AssemblyInfo.cs

@@ -36,7 +36,7 @@ using System.Runtime.InteropServices;
 // 方法是按如下所示使用“*”: :
 // [assembly: AssemblyVersion("1.0.*")]
 
-[assembly: AssemblyVersion("2.2.4.1")]
-[assembly: AssemblyFileVersion("2.2.4.1")]
+[assembly: AssemblyVersion("2.2.5.0")]
+[assembly: AssemblyFileVersion("2.2.5.0")]
 [assembly: NeutralResourcesLanguage("zh-CN")]