2009-09-09 15 views
15

ho bisogno di riutilizzare un metodo DataAccess prescritto dal cliente. Questo metodo restituisce un datatable vanilla. Voglio trasmettere questo datatable al mio Datatable digitato. La quantità di colonne e i loro tipi corrisponderanno. Il messaggio di eccezione "Impossibile eseguire il cast oggetto di tipo 'System.Data.DataTable' digitare 'MarketValueDataTable'." è molto chiaro, ma come lo risolvo?Casting generico DataTable tipizzato DataTable

Ha dato un'occhiata a casting-a-base-type-to-a-derived-type, ma non è riuscito a vedere come farlo funzionare.

Non riesco a popolare il datatable con un datareader, posso solo utilizzare il metodo DataAccess del client.

risposta

32

Il cast potrebbe funzionare solo se la tabella restituito dal metodo era in realtà un esempio di MarketValueDataTable. Se non lo è, tutto ciò che puoi fare è copiare i dati su un'istanza di MarketValueDataTable. Si potrebbe per esempio utilizza il metodo Merge:

DataTable data = GetData(); 
MarketValueDataTable myData = new MarketValueDataTable(); 
myData.Merge(data); 
+0

I Luv SO! Grazie. – callisto

+0

Ottimo .. :) – Marshal

+0

Quali sono i costi della fusione ?! – deepdive

1

Non è possibile trasmettere DataTable a MarketValueDataTable, per il semplice motivo che non eredita da esso.

Quello che devi fare è creare un'istanza di un nuovo MarketValueDataTable, quindi copiare i dati dal DataTable in esso.

provare qualcosa di simile:

MarketValueDataTable myTable = new MarketValueDataTable(); 
StringWriter writer = new StringWriter(); 
theDataTable.WriteXml(writer); 
myTable.ReadXml(new StringReader(writer.ToString())); 

(non ho ancora testato questo)

0

Se il DataTable è una tabella generica allora non può essere lanciato ad un MarketValueDataTable.

Una cosa che si può provare è creare un nuovo oggetto MarketValueDataTable e aggiungervi manualmente delle righe. Facendo un passo attraverso le righe del DataTable generico e poi passando attraverso le colonne di ogni riga è possibile utilizzare riflessione per impostare i valori di proprietà di una nuova MarketValueDataTableRow.

Qualcosa di simile a quanto segue (avviso - pseudocodice):

MarketValueDataTable mv = new MarketValueDataTable(); 
foreach(DataRow row in table.Rows) 
{ 

    MarketValueDataTableRow mvrow = mv.NewRow(); 
    foreach(DataColumn col in table.Columns) 
    { 
     PropertyInfo colProperty = mvrow.GetType().GetProperty(col.Name); 
     colProperty.SetValue(mvRow, row[col]); 
    } 
    mv.Rows.Add(mvrow); 

} 

si ottiene l'idea generale. Passare attraverso le righe della tabella generica e utilizzare la riflessione per trovare le proprietà corrispondenti nella riga di dati digitati specifici. Questo dovrebbe funzionare (ho usato lo stesso approccio in precedenza), ma il codice deve essere modificato per soddisfare le tue esigenze.

7

Utilizzare questa comoda funzione per convertire un normale DataTable in un DataTable digitato.

VB

Public Shared Function ConvertToTypedDataTable(Of T As {Data.DataTable, New})(dtBase As Data.DataTable) As T 
    Dim dtTyped As New T 
    dtTyped.Merge(dtBase) 

    Return dtTyped 
End Function 

Uso

Dim dtTyped = ConvertToTypedDataTable(Of dataset1.MyTypedDataTable)(MyUntypedDataTable) 

C#

public static T ConvertToTypedDataTable<T>(System.Data.DataTable dtBase) where T : Data.DataTable, new() 
{ 
    T dtTyped = new T(); 
    dtTyped.Merge(dtBase); 

    return dtTyped; 
} 

Uso

dataset1.MyTypedDataTable dtTyped = ConvertToTypedDataTable<dataset1.MyTypedDataTable>(MyUntypedDataTable);