2013-01-20 3 views
8

Ich führe eine LINQ-Abfrage auf einem datatable in C#.Linq auf DataTable: wählen Sie bestimmte Spalte in Datentabelle, nicht ganze Tabelle

Ich möchte bestimmte Spalten anstelle der ganzen Zeile auswählen und das Ergebnis in eine datatable eingeben. Wie kann ich das machen??

Mein 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

"Ich bekomme einen Fehler": Welchen Fehler bekommen Sie? –

+1

der Fehler ist: Der Typ 'AnonymousType # 1' kann nicht als Typ Parameter 'T' im generischen Typ oder Methode 'System.Data.DataTableExtensions.CopyToDataTable (System.Collections.Generic.IEnumerable )' verwendet werden. Es gibt keine implizite Referenzkonvertierung von 'AnonymousType # 1' zu 'System.Data.DataRow'. –

+0

möglich Duplikat von [Ausnahme mit CopyToDataTable mit LINQ-Abfrage?] (Http://stackoverflow.com/questions/1072120/exception-using-copytodatatable-with-linq-query) –

Antwort

8

Wenn Sie bereits vorher wissen, wie viele Spalten Ihre neue Datentabelle würde, können Sie etwas tun:

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

Das wird den Trick machen. Vielen Dank! –

3

Ihre select-Anweisung wird eine Folge von anonymen Typs zurückkehrt, nicht eine Folge von DataRows. CopyToDataTable() ist nur verfügbar unter IEnumerable<T> wobei T von DataRow ist oder abgeleitet ist. Sie können das Zeilenobjekt r auswählen, um CopyToDataTable darauf aufzurufen.

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

Sie können auch implement CopyToDataTable Wo der generische Typ T ist kein DataRow.

+0

Hi. Ich weiß, dass mein Code falsch ist. Die Frage ist, wie man nur zwei Spalten auswählt und nicht die ganze Zeile. –

+0

Ich habe einen Link zum Artikel in meiner Antwort hinzugefügt, http://msdn.microsoft.com/en-us/library/bb669096.aspx – Adil

+0

Kann ich den Typ als Datarow verlassen aber einfach bestimmte Spalten filtern? –

6

Hier bekomme ich nur drei bestimmte Spalten aus mainDataTable und verwenden Sie die Filter

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

Versuchen Sie Access DataTable easiest way, die Ihnen helfen kann, die perfekte Idee für den Zugriff auf DataTable, DataSet mit Linq ...

Betrachten Sie folgende Prüfung Nehmen wir an, wir haben DataTable wie unten.

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

Hier oben ist der Code für DatTable, hier gehen wir davon aus, dass es einige Daten in dieser Datentabelle zur Verfügung, und wir haben Grid zu binden Ansicht insbesondere durch einige Datenverarbeitung wie unten gezeigt.

Fläche | Menge | Atem | Länge | Preis = Menge * Atem * Länge

als wir folgende Abfrage Feuer haben, die uns genaue Ergebnis geben wird, wie wir wollen.

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

Wir müssen diese Datenvariable nur als Datenquelle zuweisen.

Durch diese einfache Linq Abfrage können wir unser bekommen alle akzeptiert, und wir können auch alle anderen LINQ-Abfragen mit diesem durchführen ...

5

LINQ ist sehr effektiv und einfach auf Listen zu verwenden, anstatt Datatable. Ich kann sehen, dass die obigen Antworten eine Schleife (für, foreach) haben, die ich nicht bevorzugen werde.

So ist die beste Sache, um eine interessante Spalte aus einer DataTable auszuwählen, verwenden Sie einfach eine DataView, um die Spalte zu filtern und verwenden Sie, wie Sie möchten.

Hier finden Sie, wie Sie dies tun.

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

Nun ist die Datatable dtTableWithOneColumn enthält nur eine Spalte (ColumnA).

Verwandte Themen