2009-08-30 2 views

Antwort

10

Übergeben Sie jede DataRow in den Klassenkonstruktor (oder verwenden Sie getters/setters) und übersetzen Sie jede Spalte in die entsprechende Eigenschaft. Seien Sie vorsichtig mit nullfähigen Spalten, um sie korrekt zu extrahieren.

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: warum müssen Sie immer das gleiche haben Ideen wie ich, und geben Sie 5 Sekunden schneller als ich :-) –

+4

Ich kann Zeit kontrollieren und Gedanken lesen. : -o – tvanfosson

+0

Was ist hier modifiziert? Ich verstehe, dass wir überprüfen sollten, ob ein Wert in der Zeile null ist, bevor Sie den Eigenschaften in der Klasse zuweisen. Aber was meinen Sie als modifiziert? – Josh

5

Eine Datentabelle enthält normalerweise viele Zeilen - möchten Sie jede Zeile in eine Objektinstanz umwandeln?

In diesem Fall könnten Sie z.B. einen Konstruktor zu Ihrem POCO Objekt hinzufügen, das ein DataRow als Parameter akzeptiert, und extrahiert dann die Bits und Stücke aus diesen DataRow:

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

und so weiter, und dann auf jedem der Zeilen, die Konstruktor ruft in den DataTable.Rows Sammlung:

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

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

und man könnte dann eine ASP.NET MVC-Ansicht oder Teilansicht auf dieser „YourPOCO“ Typ und verwenden Sie die „Liste“ Vorlage basiert erstellen eine Liste von „YourPOCO“ Instanzen in einer Listen- zu erstellen wie Display.

Marc

+0

Danke für die Erwähnung der Liste .Das machte es klarer. – Josh

1

Ich sah deine andere Frage über eine Datentabelle in der Datenzugriffsschicht verwendet. Wenn Sie POCO irgendwann zurückgeben, ist es eine gute Idee, dass Ihre DAL POCO bereits zurückgibt.

Sie würden einen SqlDataReader verwenden, um den POCO zu füllen. Dies ist leichter. Manchmal ist es einfacher, DataSet und DataTable für Listen von Einträgen zu verwenden, aber wenn Sie die Zeilen in stark typisierte POCOS transformieren, bin ich mir ziemlich sicher, dass dies der richtige Weg ist.

3

Alte Frage, jedenfalls kann dies für jemanden nützlich sein:

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

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

Verwandte Themen