簡體   English   中英

將DataRow轉換為對象

[英]Convert DataRow to object

我已經創建了通用List並填充了一些對象。 然后我在前面提到的List轉換為DataTable以在DataGridView中使用。 問題是,當我想從這個網格獲取Row時,我有DataRow。 我想把它轉換成我的對象,但不知道該怎么做。 也許你可以舉一些例子?

謝謝

好吧,如果你不能或不會使用“ORM”(對象關系映射器,如Linq-to-SQL或NHibernate - 這正是這些工具所做的,並為你做得很好),你將擁有自己這樣做。

將DataRow轉換為域對象模型是非常無聊的代碼,實際上:

public Customer ConvertRowToCustomer(DataRow row)
{
   Customer result = new Customer();

   result.ID = row.Field<int>("ID");
   result.Name = row.Field<string>("CustomerName");
   ..... // and so on

   return result;
}

這里最大的挑戰是使這個堅如磐石並處理(或避免)所有可能的錯誤(如字段為NULL等)。

另一種可能性是在域模型對象類型上有一個構造函數,它將DataRow作為參數並從中構造一個新對象。

假設您使用的是MyObject類,定義如下:

class MyObject
{
    public string Foo { get; set; }
    public int Foo { get; set; }
}

你可以這樣做:

using System.Data.DataSetExtensions;

...

List<MyObject> list = (from row in table.AsEnumerable()
                       select new MyObject
                       {
                            Foo = row.Field<string>("foo"),
                            Bar = row.Field<int>("bar")
                       }).ToList();

為什么不將對象放入BindingList <>而不是List <>? 然后,您可以跳過轉換為DataTable並再次返回練習。 您可能需要在對象上實現INotifyPropertyChanged ,但是一旦它們位於BindingList中,datagrid中的更改將自動應用於您的基礎對象。

可以通過在列標題單擊上手動排序列表,或者通過繼承BindingList <>並在其中實現排序功能來處理排序 - 然后單擊標題會自動對列表進行排序 - 無需代碼。

那么現在使用ORM更容易。 但是,如果你仍然使用舊時尚,你可以使用一個非常簡單的擴展類來為你完成這項工作,使用一些反射和泛型方法和lambda如下:

public static class MapperExtensionClass
{

        public static IEnumerable<MyClassType> ToMyClassTypeEnumerable(this DataTable table)
        {
            return table.AsEnumerable().Select(r => r.ToMyClassType());
        }

        public static MyClassType ToMyClassType(this DataRow row)
        {            
            return row.ToObject<MyClassType>();
        }

        public static T ToObject<T>(this DataRow row) where T: new()
        {
            T obj = new T();
            foreach (PropertyInfo property in typeof(T).GetProperties())
            {
                if (row.Table.Columns.Contains(property.Name))
                {
                    property.SetValue(obj, property.PropertyType.ToDefault(row[property.Name]));
                }
            }

            return obj;
        }


        public static object ToDefault(this Type type, object obj)
        {
            if (type == null)
                throw new Exception("Customized exception message");

            var method = typeof(MapperExtensionClass)
                .GetMethod("ToDefaultGeneric", BindingFlags.Static | BindingFlags.Public);

            var generic = method.MakeGenericMethod(type);

            return generic.Invoke(null, new object[] { obj });            
        }

        public static T ToDefaultGeneric<T>(object obj)
        {
            if (obj == null || obj == DBNull.Value)
            {
                return default(T); 
            }
            else
            {
                return (T)obj;
            }
        }
}

您還應該記住GridView對象可以綁定很多數據源類型。 所以從設計角度決定你應該選擇什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM