Шрифт:
Интервал:
Закладка:
<b>private readonly PropertyInfo[] _propertyInfos;</b>
<b>private readonly Dictionary<int, string> _nameDictionary;</b>
public MyDataReader(List<T> records)
{
Records = records;
<b> _propertyInfos = typeof(T).GetProperties();</b>
<b> _nameDictionary = new Dictionary<int,string>();</b>
}
Модифицируйте конструктор, чтобы он принимал строку подключения SQLConnection, а также строки для имен схемы и таблицы, куда будут вставлены записи, и добавьте для этих значений переменные уровня класса:
<b>private readonly SqlConnection _connection;</b>
<b>private readonly string _schema;</b>
<b>private readonly string _tableName;</b>
public MyDataReader(List<T> records, <b>SqlConnection connection</b>,
<b>string schema, string </b><b>tableName</b>)
{
Records = records;
_propertyInfos = typeof(T).GetProperties();
_nameDictionary = new Dictionary<int, string>();
<b> _connection = connection;</b>
<b> _schema = schema;</b>
<b> _tableName = tableName;</b>
}
Далее реализуйте метод GetSchemaTable(), который извлекает информацию SQL Server, касающуюся целевой таблицы:
public DataTable GetSchemaTable()
{
using var schemaCommand =
new SqlCommand($"SELECT * FROM {_schema}.{_tableName}", _connection);
using var reader = schemaCommand.ExecuteReader(CommandBehavior.SchemaOnly);
return reader.GetSchemaTable();
}
Модифицируйте конструктор, чтобы использовать SchemaTable для создания словаря, который содержит поля целевой таблицы в порядке их следования внутри базы данных:
public MyDataReader(List<T> records, <b>SqlConnection connection</b>,
<b>string schema, string tableName</b>)
{
...
<b> DataTable schemaTable = GetSchemaTable();</b>
<b> for (int x = 0; x<schemaTable?.Rows.Count;x++)</b>
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})<b> {</b>
<b> DataRow col = schemaTable.Rows[x];</b>
<b> var columnName = col.Field<string>("ColumnName");</b>
<b> _nameDictionary.Add(x,columnName);</b>
}
}
Теперь показанные далее методы могут быть реализованы обобщенным образом, используя полученную посредством рефлексии информацию:
public int FieldCount => _propertyInfos.Length;
public object GetValue(int i)
=> _propertyInfos
.First(x=>x.Name.Equals(_nameDictionary[i],
StringComparison.OrdinalIgnoreCase))
.GetValue(Records[_currentIndex]);
Для справки ниже приведены остальные методы, которые должны присутствовать (но не реализованы):
public string GetName(int i) => throw new NotImplementedException();
public int GetOrdinal(string name) => throw new NotImplementedException();
public string GetDataTypeName(int i) => throw new NotImplementedException();
public Type GetFieldType(int i) => throw new NotImplementedException();
public int GetValues(object[] values) => throw new NotImplementedException();
public bool GetBoolean(int i) => throw new NotImplementedException();
public byte GetByte(int i) => throw new NotImplementedException();
public long GetBytes(int i, long fieldOffset, byte[] buffer,
int bufferoffset, int length)
=> throw new NotImplementedException();
public char GetChar(int i) => throw new NotImplementedException();
public long GetChars(int i, long fieldoffset, char[] buffer,
int bufferoffset, int length)
=> throw new NotImplementedException();
public Guid GetGuid(int i) => throw new NotImplementedException();
public short GetInt16(int i) => throw new NotImplementedException();
public int GetInt32(int i) => throw new NotImplementedException();
public long GetInt64(int i) => throw new NotImplementedException();
public float GetFloat(int i) => throw new NotImplementedException();
public double GetDouble(int i) => throw new NotImplementedException();
- Понимание SQL - Мартин Грубер - Базы данных