2011-08-19 12 views
25

Mam problem z DataRow, z którym naprawdę walczę.DataRow: Wybierz wartość komórki podaną nazwą kolumny

Datarow jest odczytywany z arkusza kalkulacyjnego Excel za pomocą połączenia OleDbConnection.

Jeśli spróbuję wybrać dane z DataRow przy użyciu nazwy kolumny, zwraca ona DBNull, mimo że istnieją tam dane.

Ale to nie jest takie proste.

datarow.Table.Columns[5].ColumnName zwraca "moja kolumna".
datarow["my column"] zwraca DBNull.
datarow[5] zwraca 500.
datarow[datarow.Table.Columns[5].ColumnName] zwraca DBNull. (tylko żeby się upewnić, że to nie jest literówka!)

Mogę po prostu wybrać rzeczy z dataru używając numeru kolumny, ale nie podoba mi się to, ponieważ jeśli kolejność kolumn się zmieni, oprogramowanie się zepsuje.

+0

datarow.Table.Rows? – sll

+0

czy możesz pokazać swój kod? – Reniuz

+0

Jak wygląda Twój arkusz kalkulacyjny? Czy ma na górze puste wiersze? Jaki jest twój ciąg połączenia? Jaka jest najmniejsza ilość kodu potrzebnego do odtworzenia go, abyśmy mogli go obejrzeć? (w tym przykładowy arkusz) – Will

Odpowiedz

37

Która wersja .NET używasz? Od .NET 3.5 istnieje zestaw System.Data.DataSetExtensions, który zawiera różne przydatne rozszerzenia dla DataTables, dataRows i tym podobne.

Można spróbować użyć

row.Field<type>("fieldName"); 

jeśli to nie pomoże, można to zrobić:

DataTable table = new DataTable(); 
var myColumn = table.Columns.Cast<DataColumn>().SingleOrDefault(col => col.ColumnName == "myColumnName"); 
if (myColumn != null) 
{ 
    // just some roww 
    var tableRow = table.AsEnumerable().First(); 
    var myData = tableRow.Field<string>(myColumn); 
    // or if above does not work 
    myData = tableRow.Field<string>(table.Columns.IndexOf(myColumn)); 
} 
+0

Oznaczając to jako odpowiedź, doprowadziło mnie to do ustalenia, co się dzieje. Okazuje się, że gdy korzystam z funkcji Quick Watch, wpisałem nieprawidłowy identyfikator kolumny. Wpisanie prawidłowego identyfikatora kolumny zwróciło wartość null, mimo że w wierszu były dane.Nie jestem do końca pewien, dlaczego zwróciło wartość null, ale domyślam się, że ma to coś wspólnego z interpretacją typów danych, ponieważ był to jedyny wiersz z wartością inną niż null i zastępujący zero wartością 0 we wszystkich pozostałych wierszach sprawił, że zwróci poprawną wartość tego wiersza. – VaticanUK

4

Podpowiedź

DataTable table = new DataTable(); 
table.Columns.Add("Column#1", typeof(int)); 
table.Columns.Add("Column#2", typeof(string)); 
table.Rows.Add(5, "Cell1-1"); 
table.Rows.Add(130, "Cell2-2"); 

EDIT: Dodano więcej

string cellValue = table.Rows[0].GetCellValueByName<string>("Column#2"); 

public static class DataRowExtensions 
{ 
    public static T GetCellValueByName<T>(this DataRow row, string columnName) 
    { 
     int index = row.Table.Columns.IndexOf(columnName); 
     return (index < 0 || index > row.ItemArray.Count()) 
        ? default(T) 
        : (T) row[index];   
    } 
} 
+0

oraz w jaki sposób za pomocą tego kodu można uzyskać dane według ** nazwy kolumny **? – Reniuz

+0

@Reniuz: zaktualizowano – sll

33

To musi być nowa funkcja lub coś, w przeciwnym razie nie jestem pewien, dlaczego to nie zostało wspomniane.

Można uzyskać dostęp do wartości w kolumnie w DataRow obiektu przy użyciu row["ColumnName"]:

DataRow row = table.Rows[0]; 
string rowValue = row["ColumnName"].ToString(); 
+0

Jeśli wpis danych ma wartość NULL, wierzę, że zostanie zgłoszony błąd podczas wywoływania funkcji ToString. – Zorgarath

+0

@ Zorgarath, prawdziwy fakt. Otrzymasz również błąd, jeśli 'table' nie ma wierszy. – Jimmy

1

Na szczycie co Jimmy powiedział, można również zrobić select generic za pomocą Convert.ChangeType wraz z niezbędnymi kontroli zerowych:

public T GetColumnValue<T>(DataRow row, string columnName) 
    { 
     T value = default(T); 
     if (row.Table.Columns.Contains(columnName) && row[columnName] != null && !String.IsNullOrWhiteSpace(row[columnName].ToString())) 
     { 
      value = (T)Convert.ChangeType(row[columnName].ToString(), typeof(T)); 
     } 

     return value; 
    } 
6

I łatwiej uzyskać do niego dostęp, wykonując następujące czynności:

 for (int i = 0; i < Table.Rows.Count-1; i++) //Looping through rows 
     { 
      var myValue = Table.Rows[i]["MyFieldName"]; //Getting my field value 

     } 
Powiązane problemy