将数据从数据表传输到相应对象的好方法是什么?我猜测有一种比我目前更有效,更清洁的方法:
var username = dt_user.rows[0].columns[0];
谢谢!
答案 0 :(得分:2)
您可能会受益于此帖子中的帮助程序类:http://lozanotek.com/blog/archive/2007/05/09/Converting_Custom_Collections_To_and_From_DataTable.aspx
public class CollectionHelper
{
private CollectionHelper()
{
}
public static DataTable ConvertTo<T>(IList<T> list)
{
DataTable table = CreateTable<T>();
Type entityType = typeof(T);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);
foreach (T item in list)
{
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
{
row[prop.Name] = prop.GetValue(item);
}
table.Rows.Add(row);
}
return table;
}
public static IList<T> ConvertTo<T>(IList<DataRow> rows)
{
IList<T> list = null;
if (rows != null)
{
list = new List<T>();
foreach (DataRow row in rows)
{
T item = CreateItem<T>(row);
list.Add(item);
}
}
return list;
}
public static IList<T> ConvertTo<T>(DataTable table)
{
if (table == null)
{
return null;
}
List<DataRow> rows = new List<DataRow>();
foreach (DataRow row in table.Rows)
{
rows.Add(row);
}
return ConvertTo<T>(rows);
}
public static T CreateItem<T>(DataRow row)
{
T obj = default(T);
if (row != null)
{
obj = Activator.CreateInstance<T>();
foreach (DataColumn column in row.Table.Columns)
{
PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);
try
{
object value = row[column.ColumnName];
prop.SetValue(obj, value, null);
}
catch
{
// You can log something here
throw;
}
}
}
return obj;
}
public static DataTable CreateTable<T>()
{
Type entityType = typeof(T);
DataTable table = new DataTable(entityType.Name);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);
foreach (PropertyDescriptor prop in properties)
{
table.Columns.Add(prop.Name, prop.PropertyType);
}
return table;
}
}
To see the full code in action, check this sample out:
public class MyClass
{
public static void Main()
{
List<Customer> customers = new List<Customer>();
for (int i = 0; i < 10; i++)
{
Customer c = new Customer();
c.Id = i;
c.Name = "Customer " + i.ToString();
customers.Add(c);
}
DataTable table = CollectionHelper.ConvertTo<Customer>(customers);
foreach (DataRow row in table.Rows)
{
Console.WriteLine("Customer");
Console.WriteLine("---------------");
foreach (DataColumn column in table.Columns)
{
object value = row[column.ColumnName];
Console.WriteLine("{0}: {1}", column.ColumnName, value);
}
Console.WriteLine();
}
RL();
}
#region Helper methods
private static void WL(object text, params object[] args)
{
Console.WriteLine(text.ToString(), args);
}
private static void RL()
{
Console.ReadLine();
}
private static void Break()
{
System.Diagnostics.Debugger.Break();
}
#endregion
}
答案 1 :(得分:2)
如果您知道您期望的数据类型;你可以完美地为字符串做这个:
string username = dt_user.rows[0][0].ToString();
这是为了注册:
int userID = int.Parse(dt_user.rows[0][0].ToString());
虽然那仍然很难看。我会写几个扩展方法:
public static string ObjectToString(this object theObject)
{
if(!string.IsNullOrEmpty(theObject))
return theObject.ToString();
return string.Empty;
}
public static int ObjectToInt(this object theObject)
{
int result = 0;
if(!string.IsNullOrEmpty(theObject) && int.TryParse(theObject, out result))
{
return result;
}
return -1;
}
然后我会这样称呼它:
string username = dt_user.rows[0][0].ObjectToString();
int userid = dt_user.rows[0][0].ObjectToInt();
还有一个建议:如果不需要,请不要使用索引访问列名;你可以说dt_user.rows[0]["username"].ToString();
如果有人更改了结果集中特定列的位置,这样可以防止出现意外结果/错误。
答案 2 :(得分:2)
查看System.Data.DataSetExtensions中的扩展名。它提供了一个通用的扩展方法Field,它具有DataRow的各种重载。
var username = dt_user.rows[0].columns[0];
//becomes
var username = dt_user.rows[0].Field<String>(0);
当访问可以为空的原始类型时,真正的力量来了:
var integerValue = dataRow.Field<Int32?>("ColumnName");
可在此处找到更多信息: http://msdn.microsoft.com/en-us/library/system.data.datarowextensions.aspx