6

如何在 Asp.Net MVC 中将数据表转换为 POCO 对象?

4

4 回答 4

10

将每个 DataRow 传递给类构造函数(或使用 getter/setter)并将每一列转换为相应的属性。请注意可空列以正确提取它们。

  public class POCO
  {
       public int ID { get; set; }
       public string Name { get; set; }
       public DateTime? Modified { get; set; }
       ...

       public POCO() { }

       public POCO( DataRow row )
       {
            this.ID = (int)row["id"];
            this.Name = (string)row["name"];
            if (!(row["modified"] is DBNull))
            {
                 this.Modified = (DateTime)row["modified"];
            }
            ...
       }
  }
于 2009-08-30T14:54:03.003 回答
5

一个数据表通常包含许多行 - 您想将每一行转换为一个对象实例吗?

在这种情况下,您可以向您的 POCO 对象添加一个构造函数,该对象将接受一个DataRow作为参数,然后从中提取点点滴滴DataRow

public YourPOCO(DataRow row)
{
   this.Field1 = row["Field1"].ToString();
   ...
   this.FieldN = Convert.ToInt32(row["FieldN"]);
}

依此类推,然后在DataTable.Rows集合中的每一行上调用该构造函数:

List<YourPOCO> list = new List<YourPOCO>();

foreach(DataRow row in YourDataTable.Rows)
{
   list.Add(new YourPOCO(row));
}

然后,您可以基于此“YourPOCO”类型创建 ASP.NET MVC 视图或部分视图,并使用“List”模板在类似列表的显示中创建“YourPOCO”实例的列表。

马克

于 2009-08-30T14:54:40.507 回答
4

老问题,无论如何这对某人有用:

private static T CreatePocoObject<T>(DataRow dr) where T : class, new()
{
    try
    {
        T oClass = new T();
        Type tClass = typeof (T);
        MemberInfo[] methods = tClass.GetMethods();
        ArrayList aMethods = new ArrayList();
        object[] aoParam = new object[1];

        //Get simple SET methods
        foreach (MethodInfo method in methods)
        {
            if (method.DeclaringType == tClass && method.Name.StartsWith("set_"))
                aMethods.Add(method);
        }

        //Invoke each set method with mapped value
        for (int i = 0; i < aMethods.Count; i++)
        {
            try
            {
                MethodInfo mInvoke = (MethodInfo)aMethods[i];
                //Remove "set_" from method name
                string sColumn = mInvoke.Name.Remove(0, 4);
                //If row contains value for method...
                if (dr.Table.Columns.Contains(sColumn))
                {
                    //Get the parameter (always one for a set property)
                    ParameterInfo[] api = mInvoke.GetParameters();
                    ParameterInfo pi = api[0];

                    //Convert value to parameter type
                    aoParam[0] = Convert.ChangeType(dr[sColumn], pi.ParameterType);

                    //Invoke the method
                    mInvoke.Invoke(oClass, aoParam);
                }
            }
            catch
            {
                System.Diagnostics.Debug.Assert(false, "SetValuesToObject failed to set a value to an object");
            }
        }

        return oClass;
    }
    catch
    {
        System.Diagnostics.Debug.Assert(false, "SetValuesToObject failed to create an object");
    }

    return null;
}

来源是http://blog.developers.ie/cgreen/archive/2007/09/14/using-reflection-to-copy-a-datarow-to-a-class.aspx

于 2011-08-24T10:34:59.007 回答
1

我看到了关于在数据访问层中使用数据表的另一个问题。如果您在某个时候返回 POCO,最好让您的 DAL 已经返回 POCO。

您将使用 SqlDataReader 来填充 POCO。这是更轻的重量。有时更容易将 DataSet 和 DataTable 用于条目列表,但是如果您将行转换为 stronly 类型的 POCOS,我很确定这是要走的路。

于 2009-08-30T20:01:18.910 回答