`
zhmocean
  • 浏览: 202521 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用反射机制实现实体列表到DataTable的深层字段转换

阅读更多

  在《适配器模式在Web Service返回值中的应用》(http://blog.csdn.net/zhmnsw/archive/2007/07/23/1704235.aspx)一文中,我们使用到了IDataListAdapter接口来实现返回值数据表的转换操作,其中对于NHibernate返回的实体列表我们使用了TDlaEntityList类来进行转换。

但是,对于TDlaEntityList类型的实现,参考的一些代码只考虑到了基本数据类型字段的转换,而对于非系统定义的数据类型,或者具有组合性质的字段属性,该转换属于无效转换。比如一个Person和一个Address类型,为多对一关系,那么当Person包含一个Address类型的组合字段时,我们便无法将该字段简单的放入DataTable表中,而必须确定一个Address字段的别名字段。因此,本文描述了一种使用反射机制,填充实体列表组合字段值的方法。
一般情况下,对于基本数据类型字段,我们只需要使用PropertyInfo的GetValue方法及PropertyType属性等操作,就可以方便的将对象具有的各字段值一一读出,对于这类代码,网上有很多实现代码,在此不再赘述。
而对于我们上面提到的组合字段,由于无法预知字段嵌套的深度,比如对于多个类型连接的情况,我们可能会使用类似person.Address.Area.Areaname的语句形式来读取我们需要的映射字段值。那么,我们可不可以在使用TDlaEntityList类型进行“实体-数据记录”数据转换的时候,根据所设定的搜寻路径来自动寻找我们要转换的字段值呢?答案是肯定的,我们一步一步来。
对于TDlaEntityList类型我们应该先定义字段在DataTable中的别名、数据类型以及改别名值的搜寻路径,比如,我们设置一个组合字段的别名为BelongUserName、System.String类型,以及搜寻路径为BlongUser.UserName,那么在实体列表转换成DataTable型的时候会遵循以下算法:
1、 使用反射机制读取一个字段,并判断该字段是否为组合数据类型。
2、 如果不是,则返回该字段值,回到1。如果是,则继续。
3、 读取该组合字段的第一层字段名称(比如对于BlongUser.UserName,则返回BlongUser),并读取该层字段的值,并判断该值是否有下一级的组合字段。
4、 如果存在下一级组合字段,则去掉上层名称,回到步骤3,递归获取字段值。
5、 如果不存在下一级组合字段,且当前字段为基本数据类型,则返回该值。
6、 如果当前字段不是基本数据类型,则返回空(或者返回一个特定的快捷方式,此实现另文叙述)
注意:
      对于为空的组合字段值,直接返回空值(递归到哪层都会如此)
      如指定的搜寻路径无法找到,则返回空值
     对于指定的数据类型与实际字段数据类型的冲突,需要你自己负责
那么根据该算法,我们便可是根据指定的别名及搜寻路径,填充DataTable字段值。具体实现代码如下(.NET C#)
using System;
using System.Data;
using System.Collections;
using System.Reflection;
using QihangSoft.StringData;

namespace QihangSoft.Communication ...{


    
public class TDlaEntityList: QihangSoft.Communication.IDataListAdapter ...{
        
IDataList 成员#region IDataList 成员


        
public System.Data.DataColumnCollection ColumnList
        
...{
            
get
            
...{
                DataTable dt 
= ilistToTable();
                
return dt.Columns;
            }

        }


        
public System.Data.DataRowCollection RecordList
        
...{
            
get
            
...{
                DataTable dt 
= ilistToTable();
                
return dt.Rows;
            }

        }

        
public string ListName ...{
            
get ...{
                
return "";
            }

        }


        
public DataTable AsDataTable
        
...{
            
get
            
...{
                
return ilistToTable();
            }

        }


        
#endregion



        
public TDlaEntityList( IList entityList) ...{
            
//初始化各列表
            FEntityList = entityList;
            FRecursionPropertyList 
= new TStrList();
            FRecursionPropertyTypeList 
= new ArrayList();
        }


        
private IList FEntityList;
        
private TStrList FRecursionPropertyList; //组合属性字段名称及搜寻路径列表
        private ArrayList FRecursionPropertyTypeList; //组合字段属性类型列表

        
/**//// <summary>
        
/// 实体列表转换成DataTable
        
/// </summary>
        
/// <returns></returns>
        private DataTable ilistToTable()
        
...{
            DataTable dt 
= new DataTable();
            TStrList noSysType 
= new TStrList();
            
if ((FEntityList != null)&&(FEntityList.Count >0))
            
...{    
                
//获取反射属性信息
                System.Reflection.PropertyInfo[] columnList = getObjectPropertyInfo(FEntityList[0]);

                
//遍历属性列表,存入DataTable
                foreach(System.Reflection.PropertyInfo column in columnList)
                
...{
                
                    
//获取非系统类型字段列表,以便返回实体快捷方式
                    System.Type typeimp = System.Type.GetType(column.PropertyType.ToString());
                    
if (typeimp == null)
                    
...{
                        noSysType.addNew(column.Name, column.Name);

                        
//dt.Columns.Add(column.Name, System.Type.GetType("System.String"));            
                    }

                    
else
                    
...{
                        dt.Columns.Add(column.Name, typeimp);
                    }

                }


                
//载入递归字段类型
                for    (int a=0; a<FRecursionPropertyList.count; a++)
                
...{
                    dt.Columns.Add(FRecursionPropertyList.getName(a), (System.Type)(FRecursionPropertyTypeList[a]));
                }


                
//遍历整个IList,获取数据
                for(int i=0; i<FEntityList.Count; i++)
                
...{
                    IList TempList 
= new ArrayList();
                    
//将IList中一条记录的有效属性字段写入ArrayList
                    foreach (System.Reflection.PropertyInfo pi in columnList)
                    
...{
                        
//未在排除列表中出现的字段为有效属性字段
                        if (noSysType.valueByName(pi.Name) == TStrDefine.NULL_STR)
                        
...{
                            
object oo = pi.GetValue(FEntityList[i], null);
                            TempList.Add(oo);
                        }

                    }

                
                    
object[] itm=new object[TempList.Count + FRecursionPropertyList.count];
                    
//遍历ArrayList向object[]里放数据

                    
for (int j = 0; j < TempList.Count; j++)
                    
...{
                        itm.SetValue(TempList[j], j);
                    }

                    
//遍历递归数据
                    for(int k =0; k<FRecursionPropertyList.count; k++)
                    
...{
                        
object obj = getPropertyValue(FEntityList[i], FRecursionPropertyList.getValue(k));
                        itm.SetValue(obj, TempList.Count
+k);
                    }
        

                    
//将object[]
分享到:
评论

相关推荐

    C# DataTable 转换为 实体类对象实例

    } } //对应数据库表: //User //字段:ID、Name 那么你也许需要编写将DataTable 转换为实体对象的方法,便利DataTable.Rows 获得并填充。。 下面是我写的一个通用方法,分享+记录,便于日后直接Copy ~ 代码如下:...

    把实体类数组转换为DataTable C#

    5. 将实体数组转换为DataTable:最后,遍历实体数组并将每个实体的属性值填充到DataTable的新行中: ```csharp foreach (var entity in entities) { var row = dataTable.NewRow(); foreach (var property in ...

    获取DataTable各字段的最长值

    在展现表格时,期待单元格的宽度能适应行记录中的最长值,此方法解决获取Datatable内各字段在行记录中的最长值的问题,用于设置列宽,从而放弃浏览器的自适应宽度的鸡肋方法。

    DataTable与实体类互相转换

    实现DataTable到实体类的转换,一般会创建一个泛型方法,接受DataTable和实体类类型作为参数。这个方法通过遍历DataTable的每一行,创建对应的实体实例,并将数据填充到实体类的属性中。以下是一个简单的示例: ```...

    .net 将datatable转换为实体类LIST

    将datatable转换为实体类LIST,运用了反射和泛型的技术

    datatable 按字段绑定 datagridview

    解决 datatable 不按字段顺序 绑定 datagridview的问题

    把DataReader转换成DataTable的方法

    有时候,我们需要将DataReader中的数据转换到DataTable中以便进行更复杂的操作或进一步的数据处理。 #### 方法概述 以下是一种将DataReader转换为DataTable的方法: 1. **创建一个新的DataTable**:初始化一个空...

    datatable转实体类

    c# datatable 转实体类,用于操作

    把实体类数组转换为DataTable

    这通常通过创建一个`DataTable`实例,然后遍历实体数组,将每个实体的属性值添加到新的`DataRow`中实现。以下是一个示例代码: ```csharp using System; using System.Data; using System.Collections.Generic; ...

    反射,DataRow转换为实体类

    在本篇文章中,我们将深入探讨如何使用反射将`DataRow`对象转换为自定义的实体类。`DataRow`是.NET中的一个核心类,常用于处理数据表(DataTable)的数据。而实体类则是业务逻辑层与数据库交互的模型,它们通常代表...

    XML与DataTable相互转换

    下面将详细介绍如何实现`DataTable`到XML的转换,以及如何从XML字符串还原成`DataTable`或`DataSet`。 #### 二、`DataTable`转换为XML `DataTable`是.NET框架中用于表示内存中表格数据的一种方式。将其转换为XML...

    list转换为dataTable

    在本篇文章中,我们将深入探讨如何将一个列表(List)转换为数据表(DataTable)。这一操作在.NET框架下的数据处理中十分常见,特别是在需要将内存中的数据结构转换为可以进行进一步处理或展示的数据表格式时。 ###...

    Json字符串转换Hashtable,DataTable,DataSet方法和反转换方法

    对于反转换,即从Hashtable, DataTable, 或DataSet转换回JSON字符串,我们可以使用`JsonConvert.SerializeObject`方法。例如: ```csharp string jsonString = JsonConvert.SerializeObject(hashtable); string ...

    .net 中datatable与list泛型实体对象的互相转换

    非常方便的datatable类型与List泛型实体对象集合的互相转换,在面向对象的开发中,经常会用到的,如使用上不懂可以咨询我

    C#实现将json转换为DataTable的方法

    总结来说,将JSON转换为DataTable是C#中处理数据的一个常见需求,本文提供的方法提供了一个基础的实现思路。在实际开发中,你可能还需要根据具体需求,结合其他库如Newtonsoft.Json或System.Text.Json进行更高级的...

    Dataview转换成Datatable

    在上述代码片段中,我们看到了一个具体的场景,即如何从Dataview转换到Datatable。首先,创建了一个Datatable实例`dt1`,这是通过`ds.Tables[1]`获取的,这里的`ds`通常是一个DataSet对象,它包含了多个表...

    【ASP.NET编程知识】C#将DataTable转化为ListT.docx

    这篇文章主要讲述了如何将DataTable对象转换为List对象,使用反射机制来实现这个功能。下面是详细的知识点: 1. 使用反射机制来获取T对象的所有属性 在将DataTable对象转换为List对象时,需要使用反射机制来获取T...

    C# 维数组转换为DataTable 的三个方法

    本文将介绍如何使用 C# 将多维数组转换成 `DataTable`,这对于操作 Excel 数据并将其转化为更易于处理的格式非常有用。 #### 方法一:单列数据转换 **描述**:此方法适用于只有一个字段(即列)的情况。它接收一个...

    Datatable转实体数组

    Datatable转实体数组,人民币转换、重量转换、 转大写、数据集合转换,将数字转化为大写

Global site tag (gtag.js) - Google Analytics