zoukankan      html  css  js  c++  java
  • DataTable转换为实体集合

      1 using System;
      2 using System.Collections;
      3 using System.Collections.Generic;
      4 using System.Data;
      5 using System.Linq;
      6 using System.Reflection;
      7 using System.Text;
      8 
      9 namespace TransformDTToModel
     10 {
     11     public class TransformUtil
     12     {
     13         /// <summary>
     14         /// 将DB中改动的内容同步到泛型集合中
     15         /// </summary>
     16         /// <typeparam name="T">类型</typeparam>
     17         /// <param name="source">dt源</param>
     18         /// <param name="destinationArray">目标Model集合</param>
     19         /// <returns></returns>
     20         public static bool ConvertDataTableToModel<T>(DataTable source, List<T> destinationArray)
     21             where T : class
     22         {
     23             if (source == null || destinationArray == null || source.PrimaryKey == null || source.PrimaryKey.Count() <= 0)
     24                 return false;
     25 
     26             DataTable dtChange = source.GetChanges();
     27             if (dtChange == null)
     28                 return false;
     29 
     30             List<string> keys = new List<string>();
     31             foreach (var item in source.PrimaryKey)
     32             {
     33                 keys.Add(item.ColumnName);
     34             }
     35 
     36             return ConvertDataTableToModel(source, destinationArray, keys);
     37         }
     38 
     39         /// <summary>
     40         /// 同步table里改动的数据到泛型集合里去(新增,修改,删除)
     41         /// </summary>
     42         /// <typeparam name="T">类型</typeparam>
     43         /// <param name="source">dt源</param>
     44         /// <param name="destinationArray">目标Model集合</param>
     45         /// <param name="keyColumnArray">主键集合</param>
     46         /// <returns></returns>
     47         public static bool ConvertDataTableToModel<T>(DataTable source, List<T> destinationArray, List<string> keyColumnArray) 
     48             where T : class
     49         {
     50             if (source == null || destinationArray == null || source.Rows.Count == 0 || keyColumnArray == null || keyColumnArray.Count == 0)
     51                 return false;
     52 
     53             Type modeType = destinationArray.GetType().GetGenericArguments()[0];//模型类型
     54             PropertyInfo[] ppInfoArray = modeType.GetProperties();//公共属性集合
     55             List<PropertyInfo> listPPInfo = ppInfoArray.ToList();//方便查询
     56             //关键列
     57             List<PropertyInfo> keyPIArray = listPPInfo.FindAll(x => keyColumnArray.Contains(x.Name));
     58 
     59             List<T> listToDelete = new List<T>();
     60             //新增的数据
     61             DataRow[] drAddArray = source.Select("", "", DataViewRowState.Added);
     62 
     63             object objItem = modeType.Assembly.CreateInstance(modeType.FullName);
     64             foreach (DataRow dr in drAddArray)
     65             {
     66                 destinationArray.Add((T)objItem);
     67                 foreach (System.Reflection.PropertyInfo pi in listPPInfo)
     68                 {
     69                     pi.SetValue(destinationArray[destinationArray.Count - 1], dr[pi.Name], null);
     70                 }
     71             }
     72             //修改和删除的数据
     73             DataView dvForOP = new DataView(source);
     74             dvForOP.RowStateFilter = DataViewRowState.Deleted | DataViewRowState.ModifiedCurrent;
     75 
     76             foreach (DataRowView drv in dvForOP)
     77             {
     78                 for (int i = 0; i < destinationArray.Count; i++)
     79                 {
     80                     bool blIsTheRow = true;
     81                     //找出关键列对应的行
     82                     foreach (System.Reflection.PropertyInfo pInfo in keyPIArray)
     83                     {
     84                         object okey = pInfo.GetValue(destinationArray[i], null);
     85                         if (okey == null)
     86                             continue;
     87                         if (drv[pInfo.Name].ToString() != okey.ToString())
     88                         {
     89                             blIsTheRow = false;
     90                             break;
     91                         }
     92                     }
     93                     if (!blIsTheRow)//非本行
     94                         continue;
     95                     //根据行状态同步赋值
     96                     switch (drv.Row.RowState)
     97                     {
     98                         case DataRowState.Modified:
     99                             {
    100                                 foreach (System.Reflection.PropertyInfo pi in listPPInfo)
    101                                 {
    102                                     if (keyPIArray.Contains(pi))//主键列不更新
    103                                         continue;
    104                                     pi.SetValue(destinationArray[i], drv[pi.Name], null);
    105                                 }
    106                             } break;
    107                         case DataRowState.Deleted:
    108                             {
    109                                 listToDelete.Add(destinationArray[i]);
    110                             } break;
    111                     }
    112                 }
    113             }
    114 
    115             for (int i = 0; i < listToDelete.Count; i++)
    116             {
    117                 destinationArray.Remove(listToDelete[i]);
    118             }
    119 
    120             return true;
    121         }
    122 
    123         /// <summary>
    124         /// 将视图转换成泛型集合
    125         /// </summary>
    126         /// <typeparam name="T">类型</typeparam>
    127         /// <param name="dataView">视图</param>
    128         /// <param name="model">泛型实例</param>
    129         /// <returns></returns>
    130         public static List<T> ConvertDataViewToModel<T>(DataView dataView, T model)
    131             where T:class
    132         {
    133             List<T> listReturn = new List<T>();
    134             Type modelType = model.GetType();
    135             DataTable dt = dataView.Table;
    136             //获取model所有类型
    137             PropertyInfo[] modelProperties = modelType.GetProperties();
    138 
    139             //遍历所有行,逐行添加对象
    140             for (int i = 0; i < dt.Rows.Count; i++)
    141             {
    142                 object obj = modelType.Assembly.CreateInstance(modelType.FullName);
    143                 listReturn.Add((T)obj);
    144                 //遍历model所有属性
    145                 foreach (PropertyInfo pi in modelProperties)
    146                 {
    147                     //遍历所有列
    148                     foreach (DataColumn col in dt.Columns)
    149                     {
    150                         //如果列数据类型与model的数据类型相同、名称相同
    151                         if (col.DataType == pi.PropertyType
    152                             && col.ColumnName == pi.Name)
    153                         {
    154                             pi.SetValue(obj, dt.Rows[i][col.ColumnName], null);
    155                         }
    156                     }
    157                 }
    158             }
    159 
    160             return listReturn;
    161         }
    162 
    163         /// <summary>
    164         /// 将泛型集合类转换成DataTable
    165         /// </summary>
    166         /// <typeparam name="T">集合项类型</typeparam>
    167         /// <param name="sourceArray">集合</param>
    168         /// <param name="propertyNameArray">需要返回的列的列名,如需返回所有列,此参数传入null值</param>
    169         /// <returns>数据集(表)</returns>
    170         public static DataTable ConvertModelToDataTable<T>(IList<T> sourceArray, params string[] propertyNameArray)
    171             where T:class
    172         {
    173             List<string> propertyNameList = new List<string>();
    174             if (propertyNameArray != null)
    175                 propertyNameList.AddRange(propertyNameArray);
    176 
    177             DataTable result = new DataTable();
    178             //获取结构
    179             Type[] typeArr = sourceArray.GetType().GetGenericArguments();
    180             if (typeArr.Length == 0)
    181                 return result;
    182 
    183             PropertyInfo[] propertys = typeArr[0].GetProperties();
    184             foreach (PropertyInfo pi in propertys)
    185             {
    186                 if (propertyNameList.Count == 0)
    187                 {
    188                     result.Columns.Add(pi.Name, pi.PropertyType);
    189                 }
    190                 else
    191                 {
    192                     if (propertyNameList.Contains(pi.Name))
    193                         result.Columns.Add(pi.Name, pi.PropertyType);
    194                 }
    195             }
    196             for (int i = 0; i < sourceArray.Count; i++)
    197             {
    198                 ArrayList tempList = new ArrayList();
    199                 foreach (PropertyInfo pi in propertys)
    200                 {
    201                     if (propertyNameList.Count == 0)
    202                     {
    203                         object obj = pi.GetValue(sourceArray[i], null);
    204                         tempList.Add(obj);
    205                     }
    206                     else
    207                     {
    208                         if (propertyNameList.Contains(pi.Name))
    209                         {
    210                             object obj = pi.GetValue(sourceArray[i], null);
    211                             tempList.Add(obj);
    212                         }
    213                     }
    214                 }
    215                 object[] array = tempList.ToArray();
    216                 result.LoadDataRow(array, true);
    217             }
    218 
    219             return result;
    220         }
    221 
    222     }
    223 }
    TransformUtil
      public class People
        {
            public string Id { get; set; }
    
            public string Name { get; set; }
    
            public string Address { get; set; }
        }
    

    单元测试

    [TestClass]
        public class UnitTestForTransformDTAndModel
        {
            [TestMethod]
            public void TestConvertDataTableToModel()
            {
                DataTable dt = new DataTable();
                dt.Columns.Add("Id", typeof(string));
                dt.Columns.Add("Name", typeof(string));
                dt.Columns.Add("Address", typeof(string));
                dt.PrimaryKey = new DataColumn[] { dt.Columns[0] };
    
                dt.Rows.Add("0001", "张三", "武汉市");
                dt.Rows.Add("0002", "李四", "北京市");
                dt.AcceptChanges();
                dt.Rows.Add("0003", "王五", "深圳市");
    
                List<People> allPeople = new List<People>();
    
                TransformUtil.ConvertDataTableToModel<People>(dt, allPeople);
    
                //断言是不是只有一个数据,平且是只是修改状态的王五这个人
                Assert.AreEqual(allPeople.Count, 1);
                Assert.AreEqual(allPeople[0].Name, "王五");
            }
    
            [TestMethod]
            public void TestConvertModelToDataTable()
            {
                List<People> allPeople = new List<People>()
                {
                  new People(){ Id="0001", Name="张三", Address ="武汉市"},
                  new People(){ Id="0002", Name="李四", Address ="北京市"},
                  new People(){ Id="0003", Name="王五", Address ="深圳市"}
                };
    
                DataTable dt = TransformUtil.ConvertModelToDataTable<People>(allPeople, null);
    
    
                //断言是不是有3行数据,数据的列有3列,第1列是不是Id,第一行第二列是不是张三
                Assert.AreEqual(dt.Rows.Count, 3);
                Assert.AreEqual(dt.Columns.Count, 3);
                Assert.AreEqual(dt.Columns[0].ColumnName, "Id");
                Assert.AreEqual(dt.Rows[0][1], "张三");
            }
        }
    
  • 相关阅读:
    matlab之simulink仿真入门
    20160205.CCPP体系具体解释(0015天)
    logistic回归具体解释(二):损失函数(cost function)具体解释
    Java 垃圾回收之垃圾回收算法
    synchronized
    如何中断线程
    yield函数
    Linux
    notify和notifyAll的区别
    Sleep和Wait的区别
  • 原文地址:https://www.cnblogs.com/ziranquliu/p/4651354.html
Copyright © 2011-2022 走看看