如何将datarow转换为Object

fol*_*olk 8 c# object datarow

我在我的项目上创建了一个DataRow

DataRow datarow;
Run Code Online (Sandbox Code Playgroud)

我想将此数据转换为任何类型的对象.我怎么能这样做?

Jon*_*ago 15

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

    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);
    }
Run Code Online (Sandbox Code Playgroud)

  • 干净整洁的方法 (2认同)
  • `Convert.ChangeType` 在属性的类型可以为空时抛出异常。此外,如果您尝试设置不可设置的属性,它可能会引发另一个异常。 (2认同)

Avi*_*tal 6

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

Person person = new Person();
person.FirstName = dataRow["FirstName"] ;
person.LastName = dataRow["LastName"] ;
Run Code Online (Sandbox Code Playgroud)

要么

Person person = new Person();
person.FirstName = dataRow.Field<string>("FirstName");
person.LastName = dataRow.Field<string>("LastName");
Run Code Online (Sandbox Code Playgroud)

  • 这不叫转换!这只是任务! (2认同)

Bha*_*rat 6

我找到了一个适合我的应用的解决方案.

    // 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);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

这会将您的DataRow映射到ViewModel,如下所示.

Your_ViewModel model = CreateItemFromRow<Your_ViewModel>(row);
Run Code Online (Sandbox Code Playgroud)

  • 为我工作,尽管我的数据模型在整数类型(即 Int32 与 Int64)之间存在冲突,即使我认为我不应该这样做。将它们全部更改为 Int64 可以解决问题,但我希望找到原因。 (2认同)
  • 啊啊啊 它在您的原始帖子中。Your_ViewModel 模型 = CreateItemFromRow&lt;Your_ViewModel&gt;(row); (2认同)

Nas*_*she 5

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

public static T ToObject<T>( this DataRow dataRow )
     where T : new() {
    T item = new T();
    foreach( DataColumn column in dataRow.Table.Columns ) {
        if( dataRow[column] != DBNull.Value ) {
            PropertyInfo prop = item.GetType().GetProperty( column.ColumnName );
            if( prop != null ) {
                object result = Convert.ChangeType( dataRow[column], prop.PropertyType );
                prop.SetValue( item, result, null );
                continue;
            }
            else {
                FieldInfo fld = item.GetType().GetField( column.ColumnName );
                if( fld != null ) {
                    object result = Convert.ChangeType( dataRow[column], fld.FieldType );
                    fld.SetValue( item, result );
                }
            }
        }
    }
    return item;
}
Run Code Online (Sandbox Code Playgroud)

您可以将此代码放在当前类或全局静态类中。它需要以下命名空间...

using System;
using System.Data;
using System.Reflection;
Run Code Online (Sandbox Code Playgroud)

用法很简单...

MyClassName obj = dataRow.ToObject<MyClassName>()
Run Code Online (Sandbox Code Playgroud)


小智 5

这是一个扩展方法,允许您将 a 转换DataRow为给定的对象。

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用上面的扩展方法

foreach (DataRow row in dataTable.Rows)
{
    SomeClassType obj = row.Cast<SomeClassType>();
    // do something with your object
}
Run Code Online (Sandbox Code Playgroud)