Beschreibung:
Kopiert alle Datensätze und Spalten einer Select-Abfrage in den Arbeitsspeicher und stellt die einzelnen Werte von dort bereit. Die orginal IDataReader-Klasse kann daraufhin geschlossen werden. Zu beachten ist, je nach Select-Abfrage der benötigte Arbeitsspeicher/virtueller Speicher.
Disposed wird Zeilenweise. Also bei jeder Read-Anweisung wird der letzte Datensatz verworfen.
Die Umsetzung besteht aus 3 Dateien. Der DataReader-Klasse an sich, eine DataRecord-Klasse und eine Hilfsklasse, zum Kopieren von Datentypen.
Schlagwörter: Kopie Kopieren Datensatz Datensätze MySQL SQL Server Speicher
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
namespace MySystem.Data
{
/// <summary>
/// Kopiert die Daten eines DataReader in den Arbeitspeicher. Der Orginal DataReader kann daraufhin geschlossen werden.
/// Achtung, Klasse ist nicht threadsicher.
/// </summary>
public class MemoryDataReader : IDataReader
{
#region Felder
/// <summary>
/// True, wenn die Ressourcen bereits freigegeben wurden.
/// </summary>
private bool _isDisposed = false;
/// <summary>
/// Die Anzahl der durch SQL eingefügten, geänderten oder gelöschten Datensätze
/// </summary>
private int _recordsAffected;
/// <summary>
/// Liste mit den einzelnen Datensätzen
/// </summary>
private List<MemoryDataRecord> _records = new List<MemoryDataRecord>();
/// <summary>
/// Tabelle mit den SchemaMetaDaten der aktuellen MemoryDataReaderKlasse.
/// </summary>
private DataTable _schemaDataTable = null;
/// <summary>
/// Der aktuelle Index zum Auslesen der Datensätze.
/// </summary>
private int _currentIndex = -1;
#endregion
#region Eigenschaften
/// <summary>
/// Gibt true zurück, wenn die Abfrage eine oder mehrere Datensätze enthält, andernfals false.
/// </summary>
public bool HasRows
{
get
{
return this._records.Count > 0;
}
}
#endregion
#region Konstruktoren
/// <summary>
/// Erstellt einen neuen leeren MemoryDataReader.
/// </summary>
public MemoryDataReader()
{
}
/// <summary>
/// Erstellt einen neuen MemoryDataReader aus einer bereits bestehenden Reader-Klasse und kopiert alle Datensätze und Werte.
/// </summary>
/// <param name="reader">Der DataReader der als MemoryReader kopiert werden soll.</param>
public MemoryDataReader(IDataReader reader)
: this ()
{
if (reader == null) throw new ArgumentNullException("reader");
if (reader.IsClosed) throw new ArgumentException("Der übergebene DataReader ist bereits geschlossen");
DataTable schemaTab = reader.GetSchemaTable();
if (schemaTab != null) this._schemaDataTable = schemaTab.Clone();
this._recordsAffected = reader.RecordsAffected;
//Datensätze einzeln hinzufügen
string[] colnames = null;
while (reader.Read())
{
if (colnames == null)
{
colnames = new string[reader.FieldCount];
for (int fi = 0; fi < colnames.Length; fi++)
{
colnames[fi] = reader.GetName(fi);
}
}
this.AddRecord(reader, colnames);
}
}
~MemoryDataReader()
{
if (!this._isDisposed) this.Dispose();
}
#endregion
#region Funktionen
/// <summary>
/// Fügt einen neuen Datensatz der MemoryDataRecord-Klasse hinzu.
/// </summary>
/// <param name="record">Die Record-Klasse, die hinzugefügt werden soll.</param>
public void AddRecord(MemoryDataRecord record)
{
if (record == null) throw new ArgumentNullException("record");
if (record.IsDisposed) throw new ArgumentException("Die DataRecord-Klasse wurde bereits disposed");
this._records.Add(record);
}
/// <summary>
/// Fügt einen neuen Datensatz der MemoryDataRecord-Klasse hinzu.
/// </summary>
/// <param name="record">Die Record-Klasse, die hinzugefügt werden soll.</param>
public void AddRecord(IDataRecord record)
{
if (record == null) throw new ArgumentNullException("record");
this.AddRecord(new MemoryDataRecord(record));
}
/// <summary>
/// Fügt einen neuen Datensatz der MemoryDataRecord-Klasse hinzu.
/// </summary>
/// <param name="record">Die Record-Klasse, die hinzugefügt werden soll.</param>
/// <param name="colnames">Ein Array mit Spaltennamen (Reihenfolge beachten)</param>
public void AddRecord(IDataRecord record, string[] colnames)
{
if (record == null) throw new ArgumentNullException("record");
this.AddRecord(new MemoryDataRecord(record, colnames));
}
/// <summary>
/// Entfernt die aktuelle Record-Klasse und gibt die Ressourcen frei.
/// </summary>
protected void RemoveCurrentRecord()
{
this._records[0].Dispose();
this._records.RemoveAt(0);
}
#endregion
#region IDataReader Member
/// <summary>
/// Schließt die MemoryDataRecord-Klasse und gibt die Ressourcen wieder frei (selber Aufruf wie Dispose()).
/// </summary>
public void Close()
{
this.Dispose();
}
public int Depth
{
get
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].Depth;
}
}
/// <summary>
/// Gibt eine System.Data.DataTable zurück, die die Spaltenmetadaten der MemoryDataReader-Klasse beschreibt.
/// </summary>
/// <returns>Eine System.Data.DataTable, die die Spaltenmetadaten beschreibt</returns>
public DataTable GetSchemaTable()
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._schemaDataTable;
}
/// <summary>
/// Gibt true zurück, wenn der Reader bereits geschlossen worden ist und seine Ressourcen freigegeben wurden.
/// </summary>
public bool IsClosed
{
get { return this._isDisposed; }
}
/// <summary>
/// Prüft ob weitere Datensätze vorhanden sind und verschiebt den Zeiger auf den nächsten Datensatz
/// Selbe Funktion wie Read()
/// </summary>
/// <returns>Gibt true zurück wenn der der Zeiger nicht das Ende der Auflistung der Datensäze überschritten hat, andernfalls false.</returns>
public bool NextResult()
{
return this.Read();
}
/// <summary>
/// Prüft ob weitere Datensätze vorhanden sind und verschiebt den Zeiger auf den nächsten Datensatz.
/// Diese Funktion muss vor dem ersten abrufen der Datensätze erfolgen.
/// </summary>
/// <returns>Gibt true zurück wenn der der Zeiger nicht das Ende der Auflistung der Datensäze überschritten hat, andernfalls false.</returns>
public bool Read()
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
if (this._currentIndex == 0)
this.RemoveCurrentRecord();
else
this._currentIndex = 0;
return this._records.Count > 0;
}
/// <summary>
/// Ruft die Anzahl der durch die Ausführung der SQL-Anweisung geänderten, eingefügten oder gelöschten Zeilen ab.
/// </summary>
public int RecordsAffected
{
get
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._recordsAffected;
}
}
#endregion
#region IDisposable Member
/// <summary>
/// Gibt alle verwendeten Ressourcen frei, inklusive der einzelnen Datensätze.
/// </summary>
public void Dispose()
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
this._isDisposed = true;
this._currentIndex = -1;
this._recordsAffected = -1;
if (this._schemaDataTable != null)
{
this._schemaDataTable.Dispose();
this._schemaDataTable = null;
}
while (this._records.Count > 0)
{
this.RemoveCurrentRecord();
}
this._records = null;
}
#endregion
#region IDataRecord Member
/// <summary>
/// Ruft die Anzahl der Spalten in der aktuellen Zeile ab.
/// </summary>
public int FieldCount
{
get
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].FieldCount;
}
}
/// <summary>
/// Ruft den Wert der angegebenen Spalte als booleschen Wert ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public bool GetBoolean(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetBoolean(i);
}
/// <summary>
/// Ruft den Wert der angegebenen Spalte als 8-Bit-Ganzzahl ohne Vorzeichen ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public byte GetByte(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetByte(i);
}
/// <summary>
/// Liest beginnend am angegebenen Pufferoffset einen Stream von Bytes aus dem angegebenen Spaltenoffset als Array in den Puffer.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <param name="buffer">Der Puffer, in den der Bytestream gelesen werden soll.</param>
/// <param name="bufferoffset">Der Index für buffer, an dem der Lesevorgang beginnen soll.</param>
/// <param name="fieldOffset">Der Index im Feld, an dem der Lesevorgang beginnen soll.</param>
/// <param name="length">Die Anzahl der zu lesenden Bytes.</param>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetBytes(i, fieldOffset, buffer, bufferoffset, length);
}
/// <summary>
/// Ruft den Zeichenwert der angegebenen Spalte ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public char GetChar(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetChar(i);
}
/// <summary>
/// Liest beginnend am angegebenen Pufferoffset einen Stream von Zeichen aus dem angegebenen Spaltenoffset als Array in den Puffer.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <param name="buffer">Der Puffer, in den der Bytestream gelesen werden soll.</param>
/// <param name="bufferoffset">Der Index für buffer, an dem der Lesevorgang beginnen soll.</param>
/// <param name="fieldOffset">Der Index im Feld, an dem der Lesevorgang beginnen soll.</param>
/// <param name="length">Die Anzahl der zu lesenden Bytes.</param>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetChars(i, fieldoffset, buffer, bufferoffset, length);
}
/// <summary>
/// Ruft einen System.Data.IDataReader ab, der verwendet werden soll, wenn das Feld auf weitere strukturierte Remotedaten zeigt.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Ein System.Data.IDataReader, der verwendet werden soll, wenn das Feld auf weitere strukturierte Remotedaten zeigt.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public IDataReader GetData(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetData(i);
}
/// <summary>
/// Ruft die Datentypinformationen für das angegebene Feld ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Die Datentypinformationen für das angegebene Feld.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public string GetDataTypeName(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetDataTypeName(i);
}
/// <summary>
/// Ruft den Datums- und Uhrzeitwert des angegebenen Felds ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public DateTime GetDateTime(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetDateTime(i);
}
/// <summary>
/// Ruft den numerischen Wert für die feste Position des angegebenen Felds ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public decimal GetDecimal(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetDecimal(i);
}
/// <summary>
/// Ruft die Gleitkommazahl mit doppelter Genauigkeit des angegebenen Felds ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public double GetDouble(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetDouble(i);
}
/// <summary>
/// Ruft die System.Type-Informationen ab, die dem Typ des System.Object entsprechen, das von System.Data.IDataRecord.GetValue(System.Int32) zurückgegeben wird.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Die System.Type-Informationen, die dem Typ des System.Object entsprechen, das von System.Data.IDataRecord.GetValue(System.Int32) zurückgegeben wird.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public Type GetFieldType(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetFieldType(i);
}
/// <summary>
/// Ruft die Gleitkommazahl mit einfacher Genauigkeit des angegebenen Felds ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public float GetFloat(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetFloat(i);
}
/// <summary>
/// Gibt den GUID-Wert des angegebenen Felds zurück.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public Guid GetGuid(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetGuid(i);
}
/// <summary>
/// Ruft den Wert des angegebenen Felds als 16-Bit-Ganzzahl mit Vorzeichen ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public short GetInt16(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetInt16(i);
}
/// <summary>
/// Ruft den Wert des angegebenen Felds als 32-Bit-Ganzzahl mit Vorzeichen ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public int GetInt32(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetInt32(i);
}
/// <summary>
/// Ruft den Wert des angegebenen Felds als 64-Bit-Ganzzahl mit Vorzeichen ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public long GetInt64(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetInt64(i);
}
/// <summary>
/// Ruft den Namen des zu suchenden Felds ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Name des Felds oder eine leere Zeichenfolge (""), wenn kein zurückzugebender Wert vorhanden ist.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public string GetName(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetName(i);
}
/// <summary>
/// Zurückgeben des Indexes des benannten Felds.
/// </summary>
/// <param name="name"></param>
/// <returns>Der Name des gesuchten Felds.</returns>
public int GetOrdinal(string name)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetOrdinal(name);
}
/// <summary>
/// Ruft den Zeichenfolgenwert des angegebenen Felds ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public string GetString(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetString(i);
}
/// <summary>
/// Zurückgeben des Werts des angegebenen Felds.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public object GetValue(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetValue(i);
}
/// <summary>
/// Ruft alle Attributfelder in der Auflistung für den aktuellen Datensatz ab.
/// </summary>
/// <param name="values">Ein Array vom Typ System.Object, in das die Attributfelder kopiert werden sollen.</param>
/// <returns>Die Anzahl der Instanzen von System.Object im Array.</returns>
public int GetValues(object[] values)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].GetValues(values);
}
/// <summary>
/// Gibt zurück, ob das angegebene Feld auf NULL festgelegt ist
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Ein System.Data.IDataReader, der verwendet werden soll, wenn das Feld auf weitere strukturierte Remotedaten zeigt.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public bool IsDBNull(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0].IsDBNull(i);
}
/// <summary>
/// Ruft die Spalte mit dem angegebenen Namen ab.
/// </summary>
/// <param name="name">Der Name der zu suchenden Spalte.</param>
/// <returns>Die Spalte mit dem angegebenen Namen als System.Object.</returns>
/// <exception cref="System.IndexOutOfRangeException">Es wurde keine Spalte mit dem angegebenen Namen gefunden.</exception>
public object this[string name]
{
get
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0][name];
}
}
/// <summary>
/// Ruft die Spalte ab, die sich am angegebenen Index befindet.
/// </summary>
/// <param name="i">Der Index der abzurufenden Spalte.</param>
/// <returns>Die Spalte am angegebenen Index als System.Object.</returns>
/// <exception cref="System.IndexOutOfRangeException">Es wurde keine Spalte mit dem angegebenen Namen gefunden.</exception>
public object this[int i]
{
get
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._records[0][i];
}
}
#endregion
}
}
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Text;
namespace MySystem.Data
{
/// <summary>
/// Eine Record-Klasse, die die Daten einer Abfrage lokal im Arbeitspeicher festhält.
/// </summary>
public class MemoryDataRecord : IDataRecord, IDisposable
{
#region Felder
/// <summary>
/// Die Tiefe der Schachtelung des Datensatzes.
/// </summary>
private int _depth;
/// <summary>
/// True, wenn die Resourcen bereits freigegeben wurden.
/// </summary>
private bool _isDisposed = false;
/// <summary>
/// Eine Auflistung mit allen Werten.
/// </summary>
private object[] _values;
/// <summary>
/// Eine Auflistung mit allen Spaltenbezeichnungen.
/// </summary>
private string[] _names;
#endregion
#region Eigenschaften
/// <summary>
/// Gibt die Tiefe der Schachtelung der aktuellen Zeile zurück.
/// </summary>
public int Depth
{
get
{
return this._depth;
}
}
#endregion
#region Konstruktoren
/// <summary>
/// Erstellt eine neue MemoryDataRecord-Klasse auf Basis einer Liste.
/// </summary>
/// <param name="list">Die Liste mit den einzelnen Werten.</param>
public MemoryDataRecord(IList list)
{
if (list == null) throw new ArgumentNullException("list");
this._values = new object[list.Count];
this._names = new string[0];
for (int fi = 0; fi < this._values.Length; fi++)
{
this._values[fi] = MemoryDataHelper.GetCopyFrom(list[fi]);
}
}
/// <summary>
/// Erstellt eine neue MemoryDataRecord-Klasse auf Basis einer Liste.
/// </summary>
/// <param name="list">Die Liste mit den einzelnen Werten.</param>
/// <param name="depth">Die Tiefe des Objektes.</param>
public MemoryDataRecord(IList list, int depth)
{
if (list == null) throw new ArgumentNullException("list");
this._values = new object[list.Count];
this._names = new string[0];
for (int fi = 0; fi < this._values.Length; fi++)
{
this._values[fi] = MemoryDataHelper.GetCopyFrom(list[fi]);
}
this._depth = depth;
}
/// <summary>
/// Erstellt eine neue MemoryDataRecord-Klasse auf Basis einer Liste.
/// </summary>
/// <param name="list">Die Liste mit den einzelnen Werten.</param>
public MemoryDataRecord(object[] list)
{
if (list == null) throw new ArgumentNullException("list");
this._values = new object[list.Length];
this._names = new string[0];
for (int fi = 0; fi < this._values.Length; fi++)
{
this._values[fi] = MemoryDataHelper.GetCopyFrom(list[fi]);
}
}
/// <summary>
/// Erstellt eine neue MemoryDataRecord-Klasse auf Basis einer Liste.
/// </summary>
/// <param name="list">Die Liste mit den einzelnen Werten.</param>
/// <param name="depth">Die Tiefe des Objektes.</param>
public MemoryDataRecord(object[] list, int depth)
{
if (list == null) throw new ArgumentNullException("list");
this._values = new object[list.Length];
this._names = new string[0];
for (int fi = 0; fi < this._values.Length; fi++)
{
this._values[fi] = MemoryDataHelper.GetCopyFrom(list[fi]);
}
this._depth = depth;
}
/// <summary>
/// Erstellt eine neue MemoryDataRecord-Klasse auf Basis eines Dictionarys.
/// </summary>
/// <param name="dict">Das Dictionary mit den Spaltenwerten.</param>
public MemoryDataRecord(IDictionary dict)
{
if (dict == null) throw new ArgumentNullException("dict");
this._values = new object[dict.Count];
this._names = new string[dict.Count];
int index = 0;
foreach (object fKey in dict.Keys)
{
this._values[index] = MemoryDataHelper.GetCopyFrom(dict[fKey]);
this._names[index] = fKey.ToString();
index++;
}
}
/// <summary>
/// Erstellt eine neue MemoryDataRecord-Klasse auf Basis eines Dictionarys.
/// </summary>
/// <param name="dict">Das Dictionary mit den Spaltenwerten.</param>
/// <param name="depth">Die Tiefe des Objektes.</param>
public MemoryDataRecord(IDictionary dict, int depth)
{
if (dict == null) throw new ArgumentNullException("dict");
this._values = new object[dict.Count];
this._names = new string[dict.Count];
int index = 0;
foreach (object fKey in dict.Keys)
{
this._values[index] = MemoryDataHelper.GetCopyFrom(dict[fKey]);
this._names[index] = fKey.ToString();
index++;
}
this._depth = depth;
}
/// <summary>
/// Erstellt eine neue MemoryDataRecord-Klasse auf Basis eines bestehenden DataRecords.
/// </summary>
/// <param name="record">Der bestehende DataRecord mit den entsprechenden Spalten</param>
public MemoryDataRecord(IDataRecord record)
{
if (record == null) throw new ArgumentNullException("record");
this._values = new object[record.FieldCount];
for (int fi = 0; fi < this._values.Length; fi++)
{
this._values[fi] = MemoryDataHelper.GetCopyFrom(record[fi]);
}
this._names = new string[0];
}
/// <summary>
/// Erstellt eine neue MemoryDataRecord-Klasse auf Basis eines bestehenden DataRecords.
/// </summary>
/// <param name="record">Der bestehende DataRecord mit den entsprechenden Spalten</param>
/// <param name="depth">Die Tiefe des Objektes.</param>
public MemoryDataRecord(IDataRecord record, int depth)
{
if (record == null) throw new ArgumentNullException("record");
this._values = new object[record.FieldCount];
for (int fi = 0; fi < this._values.Length; fi++)
{
this._values[fi] = MemoryDataHelper.GetCopyFrom(record[fi]);
}
this._names = new string[0];
this._depth = depth;
}
/// <summary>
/// Erstellt eine neue MemoryDataRecord-Klasse auf Basis eines bestehenden DataRecords.
/// </summary>
/// <param name="record">Der bestehende DataRecord mit den entsprechenden Spalten</param>
/// <param name="colnames">Ein Array mit den Namen der Spalten. (Reihenfolge beachten)</param>
public MemoryDataRecord(IDataRecord record, string[] colnames)
{
if (record == null) throw new ArgumentNullException("record");
this._values = new object[record.FieldCount];
for (int fi = 0; fi < this._values.Length; fi++)
{
this._values[fi] = MemoryDataHelper.GetCopyFrom(record[fi]);
}
if (colnames == null)
this._names = new string[0];
else
this._names = colnames;
}
/// <summary>
/// Erstellt eine neue MemoryDataRecord-Klasse auf Basis eines bestehenden DataRecords.
/// </summary>
/// <param name="record">Der bestehende DataRecord mit den entsprechenden Spalten</param>
/// <param name="colnames">Ein Array mit den Namen der Spalten. (Reihenfolge beachten)</param>
/// <param name="depth">Die Tiefe des Objektes.</param>
public MemoryDataRecord(IDataRecord record, string[] colnames, int depth)
{
if (record == null) throw new ArgumentNullException("record");
this._values = new object[record.FieldCount];
for (int fi = 0; fi < this._values.Length; fi++)
{
this._values[fi] = MemoryDataHelper.GetCopyFrom(record[fi]);
}
if (colnames == null)
this._names = new string[0];
else
this._names = colnames;
this._depth = depth;
}
#endregion
#region Funktionen
#endregion
#region IDataRecord Member
/// <summary>
/// Ruft die Anzahl der Spalten in der aktuellen Zeile ab.
/// </summary>
public int FieldCount
{
get
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._values.Length;
}
}
/// <summary>
/// Ruft den Wert der angegebenen Spalte als booleschen Wert ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public bool GetBoolean(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return (bool)this._values[i];
}
/// <summary>
/// Ruft den Wert der angegebenen Spalte als 8-Bit-Ganzzahl ohne Vorzeichen ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public byte GetByte(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return (byte)this._values[i];
}
/// <summary>
/// Liest beginnend am angegebenen Pufferoffset einen Stream von Bytes aus dem angegebenen Spaltenoffset als Array in den Puffer.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <param name="buffer">Der Puffer, in den der Bytestream gelesen werden soll.</param>
/// <param name="bufferoffset">Der Index für buffer, an dem der Lesevorgang beginnen soll.</param>
/// <param name="fieldOffset">Der Index im Feld, an dem der Lesevorgang beginnen soll.</param>
/// <param name="length">Die Anzahl der zu lesenden Bytes.</param>
/// <returns>Die tatsächlich gelesene Anzahl von Bytes.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
Array.Copy((byte[])this._values[i], fieldOffset, buffer, (long)bufferoffset, (long)length);
return length;
}
/// <summary>
/// Ruft den Zeichenwert der angegebenen Spalte ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public char GetChar(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return (char)this._values[i];
}
/// <summary>
/// Liest beginnend am angegebenen Pufferoffset einen Stream von Zeichen aus dem angegebenen Spaltenoffset als Array in den Puffer.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <param name="buffer">Der Puffer, in den der Bytestream gelesen werden soll.</param>
/// <param name="bufferoffset">Der Index für buffer, an dem der Lesevorgang beginnen soll.</param>
/// <param name="fieldOffset">Der Index im Feld, an dem der Lesevorgang beginnen soll.</param>
/// <param name="length">Die Anzahl der zu lesenden Bytes.</param>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
Array.Copy((char[])this._values[i], fieldoffset, buffer, (long)bufferoffset, (long)length);
return length;
}
/// <summary>
/// Ruft einen System.Data.IDataReader ab, der verwendet werden soll, wenn das Feld auf weitere strukturierte Remotedaten zeigt.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Ein System.Data.IDataReader, der verwendet werden soll, wenn das Feld auf weitere strukturierte Remotedaten zeigt.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public IDataReader GetData(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return (IDataReader)this._values[i];
}
/// <summary>
/// Ruft die Datentypinformationen für das angegebene Feld ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Die Datentypinformationen für das angegebene Feld.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public string GetDataTypeName(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._values[i].GetType().Name;
}
/// <summary>
/// Ruft den Datums- und Uhrzeitwert des angegebenen Felds ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public DateTime GetDateTime(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return (DateTime)this._values[i];
}
/// <summary>
/// Ruft den numerischen Wert für die feste Position des angegebenen Felds ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public decimal GetDecimal(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return (decimal)this._values[i];
}
/// <summary>
/// Ruft die Gleitkommazahl mit doppelter Genauigkeit des angegebenen Felds ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public double GetDouble(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return (double)this._values[i];
}
/// <summary>
/// Ruft die System.Type-Informationen ab, die dem Typ des System.Object entsprechen, das von System.Data.IDataRecord.GetValue(System.Int32) zurückgegeben wird.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Die System.Type-Informationen, die dem Typ des System.Object entsprechen, das von System.Data.IDataRecord.GetValue(System.Int32) zurückgegeben wird.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public Type GetFieldType(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._values[i].GetType();
}
/// <summary>
/// Ruft die Gleitkommazahl mit einfacher Genauigkeit des angegebenen Felds ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public float GetFloat(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return (float)this._values[i];
}
/// <summary>
/// Gibt den GUID-Wert des angegebenen Felds zurück.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public Guid GetGuid(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return (Guid)this._values[i];
}
/// <summary>
/// Ruft den Wert des angegebenen Felds als 16-Bit-Ganzzahl mit Vorzeichen ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public short GetInt16(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return (short)this._values[i];
}
/// <summary>
/// Ruft den Wert des angegebenen Felds als 32-Bit-Ganzzahl mit Vorzeichen ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public int GetInt32(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return (int)this._values[i];
}
/// <summary>
/// Ruft den Wert des angegebenen Felds als 64-Bit-Ganzzahl mit Vorzeichen ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public long GetInt64(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return (long)this._values[i];
}
/// <summary>
/// Ruft den Namen des zu suchenden Felds ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Name des Felds oder eine leere Zeichenfolge (""), wenn kein zurückzugebender Wert vorhanden ist.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public string GetName(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
if (i < this._names.Length)
return this._names[i];
else
return "";
}
/// <summary>
/// Zurückgeben des Indexes des benannten Felds.
/// </summary>
/// <param name="name"></param>
/// <returns>Der Name des gesuchten Felds.</returns>
public int GetOrdinal(string name)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
for (int fi = 0; fi < this._names.Length; fi++)
{
if (this._names[fi].ToLower() == name.ToLower()) return fi;
}
return -1;
}
/// <summary>
/// Ruft den Zeichenfolgenwert des angegebenen Felds ab.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public string GetString(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return (string)this._values[i];
}
/// <summary>
/// Zurückgeben des Werts des angegebenen Felds.
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Der Wert der Spalte.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public object GetValue(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._values[i];
}
/// <summary>
/// Ruft alle Attributfelder in der Auflistung für den aktuellen Datensatz ab.
/// </summary>
/// <param name="values">Ein Array vom Typ System.Object, in das die Attributfelder kopiert werden sollen.</param>
/// <returns>Die Anzahl der Instanzen von System.Object im Array.</returns>
public int GetValues(object[] values)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
Array.Copy(this._values, values, 0);
return this._values.Length;
}
/// <summary>
/// Gibt zurück, ob das angegebene Feld auf NULL festgelegt ist
/// </summary>
/// <param name="i">Die nullbasierte Ordnungszahl der Spalte.</param>
/// <returns>Ein System.Data.IDataReader, der verwendet werden soll, wenn das Feld auf weitere strukturierte Remotedaten zeigt.</returns>
/// <exception cref="System.IndexOutOfRangeException">Der übergebene Index lag außerhalb des Bereichs von 0 (null) bis System.Data.IDataRecord.FieldCount.</exception>
public bool IsDBNull(int i)
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this._values[i] == DBNull.Value;
}
/// <summary>
/// Ruft die Spalte mit dem angegebenen Namen ab.
/// </summary>
/// <param name="name">Der Name der zu suchenden Spalte.</param>
/// <returns>Die Spalte mit dem angegebenen Namen als System.Object.</returns>
/// <exception cref="System.IndexOutOfRangeException">Es wurde keine Spalte mit dem angegebenen Namen gefunden.</exception>
public object this[string name]
{
get
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
int index = this.GetOrdinal(name);
if (index == -1)
throw new ArgumentOutOfRangeException(string.Format("Die Spalte \"{0}\" wurde nicht gefunden.", name));
else
return this.GetValue(index);
}
}
/// <summary>
/// Ruft die Spalte ab, die sich am angegebenen Index befindet.
/// </summary>
/// <param name="i">Der Index der abzurufenden Spalte.</param>
/// <returns>Die Spalte am angegebenen Index als System.Object.</returns>
/// <exception cref="System.IndexOutOfRangeException">Es wurde keine Spalte mit dem angegebenen Namen gefunden.</exception>
public object this[int i]
{
get
{
if (this._isDisposed) throw new Exception("MemoryDataReader ist bereits geschlossen");
return this.GetValue(i);
}
}
#endregion
#region IDisposable Member
/// <summary>
/// Gibt true zurück, wenn alle Ressourcen bereits freigegeben wurde, andernfalls false.
/// </summary>
public bool IsDisposed
{
get
{
return this._isDisposed;
}
}
/// <summary>
/// Gibt alle verwendeten Ressourcen wieder frei
/// </summary>
public void Dispose()
{
if (!this._isDisposed)
{
this._isDisposed = true;
//Alle Ressourcen freigeben
for (int fi = 0; fi < this._values.Length; fi++)
{
try
{
if (this._values[fi] is IDisposable)
{
((IDisposable)this._values[fi]).Dispose();
}
}
catch (Exception ex)
{
}
this._values[fi] = null;
}
this._values = null;
this._names = null;
}
}
#endregion
}
}
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
namespace MySystem.Data
{
/// <summary>
/// Hilfsklasse für MemoryDataReader-Klasse.
/// </summary>
class MemoryDataHelper
{
#region Objekte kopieren
/// <summary>
/// Erzeugt eine Tiefe-Kopie eines Objektes.
/// </summary>
/// <param name="value">Das orginal-Objekt, das kopiert werden soll.</param>
/// <returns>Gibt eine Kopie des Objektes zurück.</returns>
public static object GetCopyFrom(object value)
{
//Strukturen
if (value == null || value == DBNull.Value)
return DBNull.Value;
else
{
Type type = value.GetType();
if (type.IsSubclassOf(typeof(ValueType)))
return value;
else if (type == typeof(string))
return value;
else if (type == typeof(Stream))
{
MemoryStream memStream = new MemoryStream();
Stream oStream = (Stream)value;
byte[] buffer = new byte[4096];
oStream.Seek(0, SeekOrigin.Begin);
int len;
do
{
len = oStream.Read(buffer, 0, buffer.Length);
memStream.Write(buffer, 0, len);
}
while (len > 0);
return memStream;
}
else
{
using (MemoryStream memStream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(memStream, value);
object newValue = formatter.Deserialize(memStream);
return newValue;
}
}
}
}
#endregion
}
}
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...
Für Ideen, Verbesserungen, Anregungen, Fehler und sonstigem wäre ich sehr dankbar🙂
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...
Original von kleines_eichhoernchen
Beschreibung:Kopiert alle Datensätze und Spalten einer Select-Abfrage in den Arbeitsspeicher und stellt die einzelnen Werte von dort bereit. Die orginal IDataReader-Klasse kann daraufhin geschlossen werden.
Sorry für die blöde Frage, aber für was ist es gut?
Original von kleines_eichhoernchen
Für Ideen, Verbesserungen, Anregungen, Fehler und sonstigem wäre ich sehr dankbar🙂
Files zippen und hier attachen 🙂
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...