Pytanie Jak uzyskać DataRow z bieżącego wiersza DataReader?


Ok, chciałbym wyodrębnić DataRow out a DataReader. Rozglądam się od dłuższego czasu i nie wygląda na to, że jest to prosty sposób.

Rozumiem DataReader jest bardziej zbiorem wierszy, ale odczytuje tylko jeden wiersz w tym czasie.

Więc moje pytanie: czy istnieje sposób na wyodrębnienie a DataRow obecnie bieżący wiersz a DataReader?


18
2017-08-29 12:58


pochodzenie


"DataReader to więcej kolekcji wierszy" nie, to jest bardziej jak widok na pojedynczym rekordzie. ZA DataReader jest strumieniem typu "forward" do zapisów w bazie danych. Możesz tylko patrzeć na bieżący rekord. - Tim Schmelter


Odpowiedzi:


Czy istnieje sposób, aby wyodrębnić DataRow z bieżącego wiersza a   DataReader?

Nie, przynajmniej nie ma prostego sposobu. Każdy DataRow należy do jednego Stół. Nie możesz zostawić tej właściwości pustej, nie możesz nawet zmienić tabeli (bez użycia ImportRow).

Ale jeśli potrzebujesz DataRows, dlaczego nie wypełnisz DataTable na pierwszym miejscu?

DataTable table = new DataTable();
using(var con = new SqlConnection("...."))
using(var da = new SqlDataAdapter("SELECT ... WHERE...", con))
    da.Fill(table);
// now you have the row(s)

Jeśli naprawdę potrzebujesz uzyskać wiersz (y) od DataReader możesz użyć reader.GetSchemaTable aby uzyskać wszystkie informacje o kolumnach:

if (reader.HasRows)
{
    DataTable schemaTable = reader.GetSchemaTable();
    DataTable data = new DataTable();
    foreach (DataRow row in schemaTable.Rows)
    {
        string colName = row.Field<string>("ColumnName");
        Type t = row.Field<Type>("DataType");
        data.Columns.Add(colName, t);
    }
    while (reader.Read())
    {
        var newRow = data.Rows.Add();
        foreach (DataColumn col in data.Columns)
        {
            newRow[col.ColumnName] = reader[col.ColumnName];
        }
    }
}

Ale to nie jest naprawdę skuteczne.


24
2017-08-29 13:02



Dostanę tylko jeden wiersz na raz. Dlatego właśnie próbowałem DataReader było lepsze niż wypełnianie a DataTable następnie scalanie go z innymi wierszami w innym DataTable - Rémi
Twoja edycja wprowadza przyjemny punkt widzenia. Jak to naprawdę nie wygląda lepiej niż wypełnianie DataTablez jednym rzędem, a następnie łączenie. Zaznaczę jako odpowiedź, jeśli nie odpowie dokładnie na moje pytanie. - Rémi
@im_a_noob: zauważ, że przetestowałem teraz kod i zredagowałem drugi element. - Tim Schmelter


Prawdopodobnie pytasz, ponieważ masz DataReader kod, który wygląda mniej więcej tak:

static void ViaDataReader(IDataReader rdr)
{
    while (rdr.Read())
        Console.WriteLine("{0,-27} {1,-46} {2,-25} {3}", rdr[0], rdr[1], rdr[2], rdr[3]);
}

/// ...

ViaDataReader(DbProviderFactories.GetFactoryClasses().CreateDataReader());

Ale, jak wskazał Tim, jeśli ty wiedzieć z wyprzedzeniem że będziesz chciał DataRow przy każdej iteracji powinieneś użyć DataTable zamiast tego, a następnie po prostu wykonaj iterację Rows właściwość (następujące dane wyjściowe są identyczne jak powyżej):

static void ViaDataTable(IDataReader rdr)
{
    var table = new DataTable();
    table.Load(rdr);
    foreach (DataRow row in table.Rows)
        Console.WriteLine("{0,-27} {1,-46} {2,-25} {3}", row[0], row[1], row[2], row[3]);
}

/// ...

ViaDataTable(DbProviderFactories.GetFactoryClasses().CreateDataReader());

Jeśli absolutnie musisz nadal używać DataReader z jakiegoś powodu, przypuszczam, że można dodać indeks liczbowy pętli do tego pierwszego przykładu, a następnie pobrać każdy wiersz z (w pełni wstępnie załadowanego DataTable) w każdej iteracji. Ale od czasu DataTable jest bogatszy dookoła, naprawdę nie ma powodu, aby nie porzucać DataReader po wykonaniu DataTable.Load().


0
2018-03-30 05:12