2009-08-30 2 views

ответ

10

Передайте каждый DataRow в конструктор класса (или используйте геттеры/сеттеры) и переведите каждый столбец в соответствующее свойство. Будьте осторожны с нулевыми столбцами, чтобы их правильно извлечь.

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"]; 
      } 
      ... 
     } 
    } 
+0

@tvanfosson: почему вы всегда должны иметь одинаковые идеи, как я, и типа 5 секунд быстрее меня :-) –

+4

Я могу контролировать время и читать мысли. : -o – tvanfosson

+0

Что здесь изменяется? Я понимаю, что мы должны проверить, имеет ли значение в строке значение null, прежде чем назначать свойства в классе. Но, на что вы ссылаетесь, как измененный? – Josh

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)); 
} 

и вы могли бы создать представление ASP.NET MVC или частичное представление, основанное на этом типе «YourPOCO» и использовать «List» шаблон для создания списка экземпляров «YourPOCO» в list- подобный дисплей.

Марк

+0

Спасибо, что упомянул Список . Это сделало его более понятным. – Josh

1

Я видел ваш другой вопрос об использовании DataTable в слое доступа к данным. Если вы вернете POCO в какой-то момент, это хорошая идея, чтобы позволить вашему DAL возвратить POCO уже.

Вы должны использовать SqlDataReader для заполнения POCO. Это более легкий вес. Иногда его проще использовать DataSet и DataTable для списков записей, но если вы транслируете строки в строго типизированный POCOS, в любом случае, я довольно уверен, что это путь.

3

Старый вопрос, во всяком случае, это может быть полезным для кого-то:

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

Смежные вопросы