C# 如何将DataRow转换为对象

C# 如何将DataRow转换为对象,c#,object,datarow,C#,Object,Datarow,我在项目上创建了一个数据行: DataRow datarow; 我想将此数据行转换为任何类型的对象。 我怎么做呢 class Person{ public string FirstName{get;set;} public string LastName{get;set;} } Person person = new Person(); person.FirstName = dataRow["FirstName"] ; person.LastName = dataRow["LastName"

我在项目上创建了一个数据行:

DataRow datarow;
我想将此数据行转换为任何类型的对象。 我怎么做呢

class Person{
public string FirstName{get;set;}
public string LastName{get;set;}
}

Person person = new Person();
person.FirstName = dataRow["FirstName"] ;
person.LastName = dataRow["LastName"] ;

Person-Person=新的Person();
person.FirstName=dataRow.Field(“FirstName”);
person.LastName=dataRow.Field(“LastName”);

DataRow有一个属性ItemArray,其中包含一个对象值数组。您可以使用此数组并使用数据行中的值创建任何自定义类型。

除了Avi显示的手动方法外,您还可以使用类似于映射系统的方法为您进行转换。这在有许多列/属性要映射的情况下特别有用

查看如何使用AutoMapper将
数据表
转换为对象列表。

如果
转换器
是一个委托,则以下操作应有效:

List<Person> personList = new List<Person>();

personList = ConvertDataRowToList(ds, (row) => {
    return new Person
    {
        FirstName = row["FirstName"],
        LastName  = row["LastName"]
        // Rest of properties should assign here...
    };
});
List personList=new List();
personList=ConvertDataRowToList(ds,(行)=>{
换人
{
FirstName=行[“FirstName”],
LastName=行[“LastName”]
//其他属性应在此处指定。。。
};
});

我为我的应用程序找到了一个解决方案

    // function that creates an object from the given data row
    public static T CreateItemFromRow<T>(DataRow row) where T : new()
    {
        // create a new object
        T item = new T();

        // set the item
        SetItemFromRow(item, row);

        // return 
        return item;
    }

    public static void SetItemFromRow<T>(T item, DataRow row) where T : new()
    {
        // go through each column
        foreach (DataColumn c in row.Table.Columns)
        {
            // find the property for the column
            PropertyInfo p = item.GetType().GetProperty(c.ColumnName);

            // if exists, set the value
            if (p != null && row[c] != DBNull.Value)
            {
                p.SetValue(item, row[c], null);
            }
        }
    }
//从给定数据行创建对象的函数
公共静态T CreateItemFromRow(DataRow行),其中T:new()
{
//创建一个新对象
T项=新的T();
//设置项目
SetItemFromRow(项目,行);
//返回
退货项目;
}
公共静态void SetItemFromRow(T item,DataRow行),其中T:new()
{
//浏览每一列
foreach(row.Table.Columns中的数据列c)
{
//查找列的属性
PropertyInfo p=item.GetType().GetProperty(c.ColumnName);
//如果存在,请设置该值
if(p!=null&&row[c]!=DBNull.Value)
{
p、 设置值(项目,第[c]行,空);
}
}
}
这将把数据行映射到视图模型,如下所示

Your_ViewModel model = CreateItemFromRow<Your_ViewModel>(row);
Your_ViewModel model=CreateItemFromRow(row);

对于int、long、int字段,这些更改对我来说效果很好?还有多久

// function that creates an object from the given data row
public static T CreateItemFromRow<T>(DataRow row) where T : new()
{
    // create a new object
    T item = new T();

    // set the item
    SetItemFromRow(item, row);

    // return 
    return item;
}

public static void SetItemFromRow<T>(T item, DataRow row) where T : new()
{
    // go through each column
    foreach (DataColumn c in row.Table.Columns)
    {
        // find the property for the column
        PropertyInfo p = item.GetType().GetProperty(c.ColumnName);

        // if exists, set the value
        if (p != null && row[c] != DBNull.Value)
        {
            if (p.PropertyType.Name == "Int64")
            {
                p.SetValue(item, long.Parse(row[c].ToString()), null);
            }
            else if (p.PropertyType.Name == "Int32")
            {
                p.SetValue(item, int.Parse(row[c].ToString()), null);
            }
            else if (p.PropertyType.FullName.StartsWith("System.Nullable`1[[System.Int32"))
            {
                p.SetValue(item, (int?)int.Parse(row[c].ToString()), null);
            }
            else if (p.PropertyType.FullName.StartsWith("System.Nullable`1[[System.Int64"))
            {
                p.SetValue(item, (long?)long.Parse(row[c].ToString()), null);
            }
            else
            {
                p.SetValue(item, row[c], null);
            }
        }
    }
}
//从给定数据行创建对象的函数
公共静态T CreateItemFromRow(DataRow行),其中T:new()
{
//创建一个新对象
T项=新的T();
//设置项目
SetItemFromRow(项目,行);
//返回
退货项目;
}
公共静态void SetItemFromRow(T item,DataRow行),其中T:new()
{
//浏览每一列
foreach(row.Table.Columns中的数据列c)
{
//查找列的属性
PropertyInfo p=item.GetType().GetProperty(c.ColumnName);
//如果存在,请设置该值
if(p!=null&&row[c]!=DBNull.Value)
{
如果(p.PropertyType.Name==“Int64”)
{
p、 SetValue(item,long.Parse(行[c].ToString()),null);
}
else if(p.PropertyType.Name==“Int32”)
{
p、 SetValue(item,int.Parse(行[c].ToString()),null);
}
else if(p.PropertyType.FullName.StartsWith(“System.Nullable`1[[System.Int32”))
{
p、 SetValue(item,(int?)int.Parse(行[c].ToString()),null);
}
else if(p.PropertyType.FullName.StartsWith(“System.Nullable`1[[System.Int64”))
{
p、 SetValue(item,(long?)long.Parse(row[c].ToString()),null);
}
其他的
{
p、 设置值(项目,第[c]行,空);
}
}
}
}

这是我使用它的一种非常酷的方式

    public static T ToObject<T>(this DataRow dataRow)
    where T : new()
    {
        T item = new T();

        foreach (DataColumn column in dataRow.Table.Columns)
        {
            PropertyInfo property = GetProperty(typeof(T), column.ColumnName);

            if (property != null && dataRow[column] != DBNull.Value && dataRow[column].ToString() != "NULL")
            {
                property.SetValue(item, ChangeType(dataRow[column], property.PropertyType), null);
            }
        }

        return item;
    }

    private static PropertyInfo GetProperty(Type type, string attributeName)
    {
        PropertyInfo property = type.GetProperty(attributeName);

        if (property != null)
        {
            return property;
        }

        return type.GetProperties()
             .Where(p => p.IsDefined(typeof(DisplayAttribute), false) && p.GetCustomAttributes(typeof(DisplayAttribute), false).Cast<DisplayAttribute>().Single().Name == attributeName)
             .FirstOrDefault();
    }

    public static object ChangeType(object value, Type type)
    {
        if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
        {
            if (value == null)
            {
                return null;
            }

            return Convert.ChangeType(value, Nullable.GetUnderlyingType(type));
        }

        return Convert.ChangeType(value, type);
    }
公共静态T对象(此数据行数据行)
其中T:new()
{
T项=新的T();
foreach(dataRow.Table.Columns中的DataColumn列)
{
PropertyInfo property=GetProperty(typeof(T),column.ColumnName);
if(property!=null&&dataRow[column]!=DBNull.Value&&dataRow[column].ToString()!=“null”)
{
SetValue(项,变更类型(dataRow[column],property.PropertyType),null);
}
}
退货项目;
}
私有静态属性Info GetProperty(类型类型,字符串attributeName)
{
PropertyInfo属性=type.GetProperty(attributeName);
if(属性!=null)
{
归还财产;
}
返回类型。GetProperties()
.Where(p=>p.IsDefined(typeof(DisplayAttribute),false)和&p.GetCustomAttributes(typeof(DisplayAttribute),false)。Cast().Single().Name==attributeName)
.FirstOrDefault();
}
公共静态对象ChangeType(对象值、类型)
{
if(type.IsGenericType&&type.GetGenericTypeDefinition().Equals(typeof(null)))
{
如果(值==null)
{
返回null;
}
返回Convert.ChangeType(值,null.getUnderlineType(类型));
}
返回Convert.ChangeType(值,类型);
}

与前面的一些方法类似,我为
DataRow
创建了这个扩展方法,它接受一个要填充的参数对象。主要区别在于,除了填充对象的属性外,它还填充给定对象的字段。这也适用于更简单的结构(尽管我只测试了对象)

用法很简单

MyClassName obj = dataRow.ToObject<MyClassName>()
MyClassName obj=dataRow.ToObject()

这里有一个扩展方法,允许您将
数据行
转换为给定对象

public static class DataRowExtensions
{
    public static T Cast<T>(this DataRow dataRow) where T : new()
    {
        T item = new T();

        IEnumerable<PropertyInfo> properties = item.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
                                                             .Where(x => x.CanWrite);

        foreach (DataColumn column in dataRow.Table.Columns)
        {
            if (dataRow[column] == DBNull.Value)
            {
                continue;
            }

            PropertyInfo property = properties.FirstOrDefault(x => column.ColumnName.Equals(x.Name, StringComparison.OrdinalIgnoreCase));

            if (property == null)
            {
                continue;
            }

            try
            {
                Type t = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;

                object safeValue = (dataRow[column] == null) ? null : Convert.ChangeType(dataRow[column], t);

                property.SetValue(item, safeValue, null);
            }
            catch
            {
                throw new Exception($"The value '{dataRow[column]}' cannot be mapped to the property '{property.Name}'!");
            }

        }

        return item;
    }
}
公共静态类DataRowExtensions
{
公共静态T Cast(此DataRow DataRow),其中T:new()
{
T项=新的T();
IEnumerable properties=item.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
。其中(x=>x.CanWrite);
foreach(DataC
using System;
using System.Data;
using System.Reflection;
MyClassName obj = dataRow.ToObject<MyClassName>()
public static class DataRowExtensions
{
    public static T Cast<T>(this DataRow dataRow) where T : new()
    {
        T item = new T();

        IEnumerable<PropertyInfo> properties = item.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
                                                             .Where(x => x.CanWrite);

        foreach (DataColumn column in dataRow.Table.Columns)
        {
            if (dataRow[column] == DBNull.Value)
            {
                continue;
            }

            PropertyInfo property = properties.FirstOrDefault(x => column.ColumnName.Equals(x.Name, StringComparison.OrdinalIgnoreCase));

            if (property == null)
            {
                continue;
            }

            try
            {
                Type t = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;

                object safeValue = (dataRow[column] == null) ? null : Convert.ChangeType(dataRow[column], t);

                property.SetValue(item, safeValue, null);
            }
            catch
            {
                throw new Exception($"The value '{dataRow[column]}' cannot be mapped to the property '{property.Name}'!");
            }

        }

        return item;
    }
}
foreach (DataRow row in dataTable.Rows)
{
    SomeClassType obj = row.Cast<SomeClassType>();
    // do something with your object
}
    public static IDictionary<string, object> ToDictionary(
        this DataRow content
        )
    {
        var values = content.ItemArray;
        var columns = content
            .Table
            .Columns
            .Cast<DataColumn>()
            .Select(x => x.ColumnName);
        return values
            .Select((v, m) => new { v, m })
            .ToDictionary(
                x => columns.ElementAt(x.m)
                , x => (x.v == DBNull.Value ? null : x.v)
             );
    }
    public static T MapToEntity<T>(
        this IDictionary<string, object> source
        )
        where T : class, new()
    {
        // t - target
        T t_object = new T();
        Type t_type = t_object.GetType();

        foreach (var kvp in source)
        {
            PropertyInfo t_property = t_type.GetProperty(kvp.Key);
            if (t_property != null)
            {
                t_property.SetValue(t_object, kvp.Value);
            }
        }
        return t_object;
    }
DataRow dr = getSomeDataRow(someArgs);
ABC result = dr.ToDictionary()
  .MapToEntity<ABC>();