2016-07-26 13 views
0

Ich versuche, Datensätze aus DataTable nach dem Zufallsprinzip mit einigen Einschränkungen abrufen. Ich bin in der Lage, die Daten wie folgt zufällig zu holen -C# - So wählen Sie verschiedene zufällige Datensätze aus Datentabelle

var r = new Random(); 
var _randomSelection = dt.Rows.OfType<DataRow>().OrderBy(rand => r.Next()).Take(limit); 

Aber die Werte scheint redundant zu sein. Ich möchte die einzigartigen Werte erhalten. Bisher habe ich versucht Distinct() as -

var _randomSelection = dt.Rows.OfType<DataRow>().OrderBy(rand => r.Next()).Take(limit).Distinct(); 

Aber das scheint nicht ausgearbeitet werden. Kann mir jemand bitte sagen, wo ich falsch liege? Vielen Dank.

+1

definieren einzigartige erste, die Spalte (n) gibt die Taste (n) für den Rekord? Gegenwärtig kann 'Distinct' nur DataRow-Referenzen vergleichen, die alle unterschiedlich sind. –

+0

Sie sollten auch die Reihenfolge ändern, zuerst 'Distinct()' und dann 'Take' verwenden, da sonst oft weniger Daten als angefordert – Adassko

+0

@TimSchmelter beim Abrufen des Datensatzes der Spalte" ID "angezeigt werden. Ich habe meine Abfrage in SSMS getestet und dabei eindeutige Datensätze abgerufen. Scheint aber etwas mit der Zufallsfunktion zu haben. Deshalb erhalte ich doppelte Werte – arpymastro

Antwort

1
DataTable returnVals = dt.DefaultView.ToTable(true, "ColumnNameOnWhichYouWantDistinctRecords"); 

In ToTable Methode der erste Parameter gibt an, ob Sie Distinct Aufzeichnungen wollen, die zweite, durch die Spaltennamen angeben wir verschiedene machen.

Danach, wenn Sie eine bestimmte Anzahl davon nehmen wollen Sie

var result = returnVals.Rows.Cast<DataRow>().OrderBy(rand => r.Next()).Take(number); 
+0

Ich sehe keinen redundanten Datensatz in DataTable. Aber wenn ich versuche, die Datensätze aus DataTable ** nach dem Zufallsprinzip ** abrufen, scheint, dass meine Daten sich wiederholend verursacht haben. – arpymastro

+0

Fügen Sie die Reihenfolge für die zweite Zeile hinzu. – mybirthname

+0

Wie wäre es mit einem "DISTINCT" Schlüsselwort in der Abfrage selbst? Nur neugierig! – arpymastro

0

tun können, wenn Sie nach einer Spalte eindeutige Datensätze wollen:

var distinctRows = from r in table.AsEnumerable() 
        let id = r.Field<int>("Id") 
        group r by id into idGroup 
        select idGroup.First(); 

Wenn Sie mehrere nach eindeutige Datensätze wollen Spalten, verwenden Sie einen anonymen Typ:

var distinctRows = from r in table.AsEnumerable() 
        let keyCols = new { id= r.Field<int>("Id"), col2 = r.Field<string>("Col2")} 
        group r by keyCols into keyGroup 
        select keyGroup.First(); 

wenn Sie eine dynamische Möglichkeit, alle Spalten vergleichen möchten mns selbst wenn Sie sie nicht wissen:

public static class DataTableExtensions 
{ 
    public class DataRowValuesComparer : IEqualityComparer<DataRow> 
    { 
     public bool Equals(DataRow x, DataRow y) 
     { 
      if(ReferenceEquals(x, y)) 
       return true; 
      if (x == null || y == null) 
       return false; 
      if (!ReferenceEquals(x.Table, y.Table)) 
       return false; // different tables 
      foreach (DataColumn column in x.Table.Columns) 
      { 
       object v1 = x[column]; 
       object v2 = y[column]; 
       if (ReferenceEquals(v1, v2)) continue; 
       if (v1 == null || v2 == null) return false; 
       if (!v1.Equals(v2)) return false; 
      } 
      return true; 
     } 

     public int GetHashCode(DataRow obj) 
     { 
      if (obj == null) return int.MinValue; 
      unchecked 
      { 
       int hash = 19; 
       foreach (DataColumn column in obj.Table.Columns) 
       { 
        object value = obj[column]; 
        hash = hash * 31 + (value?.GetHashCode() ?? 0); 
       } 
       return hash; 
      } 
     } 
    } 

    public static IEnumerable<DataRow> DistinctValues(this IEnumerable<DataRow> rows) 
    { 
     return rows.Distinct(new DataRowValuesComparer()); 
    } 
} 

Verbrauch:

var distinctRows = table.AsEnumerable().DistinctValues(); 
Verwandte Themen