fetch datarow到c#对象 [英] fetch datarow to c# object

查看:722
本文介绍了fetch datarow到c#对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类Item表示列表中的项目。我有在它的函数调用存储过程,返回datatable,我需要将datatable转换为项目的数组。
这是我做的:

  public class Item 
{
private string _ItemIdDataName = item_id;
private string _ItemNameDataName =item_name;
private string _PriceDataName =price;

public long ItemId {get;组; }
public string ItemName {get;组; }
public float Price {get;组; }

private Item(DataRow row)
{
if(row!= null)
{
ItemId = long.Parse(row [_ItemIdDataName] .ToString());
ItemName = row [_ItemNameDataName] .ToString();
Price = float.Parse(row [_PriceDataName] .ToString());
}
}

public Item [] load()
{
DataTable dt = DBHandler.GetItems(); //返回DataTable的存储过程
Item [] items = new Item [dt.Rows.Count];
for(int i = 0; i {
items [i] = new Item(dt.Rows [i]);
}
return item;
}
}

我这样做吗?
我如何改进这个?

解决方案

如果你只想使用它一旦它可能很好,你会做很多你应该尝试做一些更通用的东西。我写了一篇博客文章,关于如何为 DataTable 编写一个扩展方法,创建一个对象列表。它的工作原理的约定,对象中的属性应该具有与存储过程中的列相同的名称(如果我可以更改存储过程中的名称):

  public static class DataTableExtensions 
{
public static IList< T> ToList< T>(此DataTable表)其中T:new()
{
IList< PropertyInfo> properties = typeof(T).GetProperties()。ToList();
IList< T> result = new List< T>();

foreach(table.Rows中的var row)
{
var item = CreateItemFromRow< T>((DataRow)row,properties);
result.Add(item);
}

返回结果;
}

public static IList< T> ToList< T>(此DataTable表,Dictionary< string,string>映射)其中T:new()
{
IList< PropertyInfo> properties = typeof(T).GetProperties()。ToList();
IList< T> result = new List< T>();

foreach(table.Rows中的var row)
{
var item = CreateItemFromRow< T>((DataRow)row,properties,mappings);
result.Add(item);
}

返回结果;
}

private static T CreateItemFromRow< T>(DataRow row,IList< PropertyInfo> properties)其中T:new()
{
T item = new T ();
foreach(属性中的var属性)
{
property.SetValue(item,row [property.Name],null);
}
return item;
}

private static T CreateItemFromRow< T>(DataRow row,IList< PropertyInfo> properties,Dictionary< string,string> mappingpings)其中T:new()
{
T item = new T();
foreach(属性中的var属性)
{
if(mappings.ContainsKey(property.Name))
property.SetValue(item,row [mappings [property.Name]] , 空值);
}
return item;
}
}

现在您可以拨打

  var items = dt.ToList< Item>(); 

  var mappings = new Dictionary< string,string>(); 
mappings.Add(ItemId,item_id);
mappings.Add(ItemName,item_name);
mappings.Add(Price,price);
var items = dt.ToList< Item>(mappings);

博客帖子在这里: http://blog.tomasjansson.com/2010/11/convert-datatable-to-generic-list-extension



有是许多方法可以扩展这个,你可以包括一些映射字典告诉扩展如何映射列,这样的名称不需要匹配或者你可以添加一个属性名称列表

更新:您的对象( Item )你创建的必须有一个默认构造函数,否则私有方法将无法创建它。由于解决方案的工作方式是首先创建对象,而不是使用您从反射获得的属性设置对象的值。



更新2:我添加了带有映射字典的部分,但没有自己尝试,所以它可能无法编译。但是,这个概念存在,我认为它的工作。


I have an class Item that represents an item in a list. I have in it function that calls stored procedure that returns datatable and I need to convert the datatable to Array of items. Here is what I do:

public class Item
{
    private string _ItemIdDataName = "item_id";
    private string _ItemNameDataName = "item_name";
    private string _PriceDataName = "price";

    public long ItemId { get; set; }
    public string ItemName { get; set; }
    public float Price { get; set; }

    private Item(DataRow row)
    {
        if (row != null)
        {
            ItemId = long.Parse(row[_ItemIdDataName].ToString());
            ItemName = row[_ItemNameDataName].ToString();
            Price = float.Parse(row[_PriceDataName].ToString());
        }
    }

    public Item[] load()
    {
        DataTable dt=DBHandler.GetItems();//Stored procedure that returns DataTable 
        Item[] items = new Item[dt.Rows.Count];
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            items[i] = new Item(dt.Rows[i]);
        }
        return items;
    }
}

Am I doing it right? How can I improve this?

解决方案

If you're only gonna use it once it probably fine, but if you'll do it a lot you should try to do some more generic stuff. I wrote a blog post about how to write an extension method for DataTable that creates a list of objects. It works by the convention that the properties in the object should have the same name as the columns in the stored procedure (I would change the name in the stored procedure if I could):

public static class DataTableExtensions
{
    public static IList<T> ToList<T>(this DataTable table) where T : new()
    {
        IList<PropertyInfo> properties = typeof(T).GetProperties().ToList();
        IList<T> result = new List<T>();

        foreach (var row in table.Rows)
        {
            var item = CreateItemFromRow<T>((DataRow)row, properties);
            result.Add(item);
        }

        return result;
    }

    public static IList<T> ToList<T>(this DataTable table, Dictionary<string, string> mappings) where T : new()
    {
        IList<PropertyInfo> properties = typeof(T).GetProperties().ToList();
        IList<T> result = new List<T>();

        foreach (var row in table.Rows)
        {
            var item = CreateItemFromRow<T>((DataRow)row, properties, mappings);
            result.Add(item);
        }

        return result;
    }

    private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties) where T : new()
    {
        T item = new T();
        foreach (var property in properties)
        {
            property.SetValue(item, row[property.Name], null);
        }
        return item;
    }

    private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties, Dictionary<string, string> mappings) where T : new()
    {
        T item = new T();
        foreach (var property in properties)
        {
            if(mappings.ContainsKey(property.Name))
                property.SetValue(item, row[mappings[property.Name]], null);
        }
        return item;
    }
}

Now you can just call

var items = dt.ToList<Item>();

or

var mappings = new Dictionary<string,string>();
mappings.Add("ItemId", "item_id");
mappings.Add("ItemName ", "item_name");
mappings.Add("Price ", "price);
var items = dt.ToList<Item>(mappings);

The blog post is here: http://blog.tomasjansson.com/2010/11/convert-datatable-to-generic-list-extension

There are many ways in which you can extend this, you could include some kind of mapping dictionary telling the extension how to map the columns, in that way the names doesn't need to match. Or you can add a list of property names that you would like to exclude in the mapping.

Update: Your object (Item) you are creating must have a default constructor otherwise the private method won't be able to create it. Since the way the solution works is first to create the object than use the properties that you get from the reflection to set the values of the object.

Update 2: I added the part with mappings dictionary but haven't tried it myself so it might not compile. However, the concept is there and I think it works.

这篇关于fetch datarow到c#对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆