2013-01-20 20 views
8

Sto eseguendo una query LINQ su un datatable in C#.Linq su DataTable: selezionare la colonna specifica nella tabella datatable, non intera

Desidero selezionare colonne specifiche anziché l'intera riga e inserire il risultato in datatable. Come lo posso fare??

My Code:

public DataTable getConversions(string c_to, string p_to) 
{ 
    var query = from r in matrix.AsEnumerable() 
       where r.Field<string>("c_to") == c_to && 
         r.Field<string>("p_to") == p_to 
       select r; 

    DataTable conversions = query.CopyToDataTable(); 
+2

"Ho ricevuto un errore": quale errore ottieni? –

+1

l'errore è: Il tipo 'AnonymousType # 1' non può essere utilizzato come parametro di tipo 'T' nel tipo generico o metodo 'System.Data.DataTableExtensions.CopyToDataTable (System.Collections.Generic.IEnumerable )'. Non esiste alcuna conversione implicita del riferimento da "AnonymousType # 1" a "System.Data.DataRow". –

+0

possibile duplicato di [Eccezione utilizzando CopyToDataTable con query LINQ?] (Http://stackoverflow.com/questions/1072120/exception-using-copytodatatable-with-linq-query) –

risposta

8

Se già sapere in anticipo quante colonne vostro nuovo DataTable avrebbe, si può fare qualcosa di simile:

DataTable matrix = ... // get matrix values from db 

DataTable newDataTable = new DataTable(); 
newDataTable.Columns.Add("c_to", typeof(string)); 
newDataTable.Columns.Add("p_to", typeof(string)); 

var query = from r in matrix.AsEnumerable() 
      where r.Field<string>("c_to") == "foo" && 
        r.Field<string>("p_to") == "bar" 
      let objectArray = new object[] 
      { 
       r.Field<string>("c_to"), r.Field<string>("p_to") 
      } 
      select objectArray; 

foreach (var array in query) 
{ 
    newDataTable.Rows.Add(array); 
} 
+0

Questo farà il trucco. Grazie! –

3

tuo select sta tornando una sequenza di tipo anonimo, non è una sequenza di DataRow. CopyToDataTable() è disponibile solo su IEnumerable<T> dove T è o deriva da DataRow. È possibile selezionare r l'oggetto riga per chiamare CopyToDataTable su di esso.

var query = from r in matrix.AsEnumerable() 
       where r.Field<string>("c_to") == c_to && 
         r.Field<string>("p_to") == p_to 
       select r; 

DataTable conversions = query.CopyToDataTable(); 

È inoltre possibile implement CopyToDataTable Dove il tipo generico T non è un DataRow.

+0

Ciao. So che il mio codice non è corretto. la domanda è qual è il modo corretto per selezionare solo due colonne e non l'intera riga. –

+0

Ho aggiunto il collegamento all'articolo nella mia risposta per farlo, http://msdn.microsoft.com/en-us/library/bb669096.aspx – Adil

+0

Posso lasciare il tipo come un datarow ma semplicemente filtrare colonne specifiche? –

6

Qui ho solo tre colonne specifiche da mainDataTable e utilizzare il filtro

DataTable checkedParams = mainDataTable.Select("checked = true").CopyToDataTable() 
.DefaultView.ToTable(false, "lagerID", "reservePeriod", "discount"); 
5

Prova Access DataTable easiest way che può aiutarti a ottenere l'idea perfetta per accedere a DataTable, DataSet usando Linq ...

Considerare il seguente esame ple, supponiamo di avere DataTable come di seguito.

DataTable ObjDt = new DataTable("List"); 
ObjDt.Columns.Add("WorkName", typeof(string)); 
ObjDt.Columns.Add("Price", typeof(decimal)); 
ObjDt.Columns.Add("Area", typeof(string)); 
ObjDt.Columns.Add("Quantity",typeof(int)); 
ObjDt.Columns.Add("Breath",typeof(decimal)); 
ObjDt.Columns.Add("Length",typeof(decimal)); 

Qui sopra è il codice per DatTable, qui si assume che vi sono alcuni dati sono disponibili in questo DataTable, e dobbiamo impegnare vista schematica del particolare elaborando alcuni dati come mostrato sotto.

Area | Quantità | Respiro | Lunghezza | Prezzo = Quantità * respiro * Lunghezza

di quello che abbiamo al fuoco seguente query che ci darà risultato esatto come vogliamo.

var data = ObjDt.AsEnumerable().Select 
      (r => new 
      { 
       Area = r.Field<string>("Area"), 
       Que = r.Field<int>("Quantity"), 
       Breath = r.Field<decimal>("Breath"), 
       Length = r.Field<decimal>("Length"), 
       totLen = r.Field<int>("Quantity") * (r.Field<decimal>("Breath") * r.Field<decimal>("Length")) 
      }).ToList(); 

Non ci resta che assegnare questa variabile di dati come origine dati.

Utilizzando questa semplice query LINQ che possiamo ottenere tutto il nostro accetta, e anche noi in grado di eseguire tutte le altre query LINQ con questo ...

5

LINQ è molto efficace e facile da usare sulle liste piuttosto che DataTable. Posso vedere le risposte sopra hanno un ciclo (for, foreach), che non preferirò.

Quindi la cosa migliore per selezionare una colonna perticular da un DataTable è semplicemente utilizzare un DataView per filtrare la colonna e utilizzarla come si desidera.

Trovalo qui come fare.

DataView dtView = new DataView(dtYourDataTable); 
DataTable dtTableWithOneColumn= dtView .ToTable(true, "ColumnA"); 

Ora la DataTable dtTableWithOneColumn contiene solo una colonna (ColumnA).