2009-08-30 8 views

risposta

10

Passare ogni DataRow nel costruttore della classe (o utilizzare getter/setter) e tradurre ogni colonna nella proprietà corrispondente. Fai attenzione con le colonne nullable per estrarle correttamente.

+0

@tvanfosson: perché devi sempre avere lo stesso idee come me, e digito 5 secondi più veloce di me :-) –

+4

Posso controllare il tempo e leggere le menti. : -o – tvanfosson

+0

Cosa viene modificato qui? Capisco che dovremmo controllare se qualsiasi valore nella riga è nullo prima di assegnarlo alle proprietà nella classe. Ma a cosa ti riferisci come modificato? – Josh

5

Una tabella di dati contiene in genere molte righe: si desidera convertire ogni riga in un'istanza di oggetto?

In tal caso, è possibile ad es. aggiungere un costruttore al vostro oggetto POCO che accetterà un DataRow come parametro, e poi estrae i pezzi di quel DataRow:

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

e così via, e quindi chiamare quel costruttore su ciascuna delle righe nel DataTable.Rows collezione:

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

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

e si potrebbe quindi creare una vista ASP.NET MVC o vista parziale sulla base di questo tipo "YourPOCO" e utilizzare il modello "lista" per creare un elenco di istanze "YourPOCO" in una lista- come display.

Marc

+0

Grazie per aver menzionato l'elenco . Ciò lo ha reso più chiaro. – Josh

1

ho visto la tua altra domanda sull'utilizzo di un DataTable nel livello di accesso ai dati. Se restituisci POCO ad un certo punto è una buona idea lasciare che il tuo DAL restituisca POCO già.

Si utilizzerà SqlDataReader per riempire il POCO. Questo è più leggero. A volte è più semplice usare DataSet e DataTable per gli elenchi delle voci, ma se si trasformano le righe in POCOS con caratteri stroncati, comunque sono abbastanza sicuro che questa è la strada da percorrere.

3

vecchia questione, in ogni caso questo può essere utile per qualcuno:

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

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

Problemi correlati