[英]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.