Язык программирования C#9 и платформа .NET5
public interface IDataAdapter{MissingMappingAction MissingMappingAction { get; set; }MissingSchemaAction MissingSchemaAction { get; set; }ITableMappingCollection TableMappings { get; }DataTable[] FillSchema(DataSet dataSet, SchemaType schemaType);int Fill(DataSet dataSet);IDataParameter[] GetFillParameters();int Update(DataSet dataSet);}Роль интерфейсов IDataReader и IDataRecord
Следующим основным интерфейсом является
, который представляет общие линии поведения, поддерживаемые отдельно взятым объектом чтения данных. После получения от поставщика данных ADO.NET объекта совместимого сIDataReaderтипа можно выполнять проход по результирующему набору в прямом направлении с поддержкой только чтения.IDataReaderpublic interface IDataReader : IDisposable, IDataRecord{// Плюс члены интерфейса IDataRecordint Depth { get; }bool IsClosed { get; }int RecordsAffected { get; }void Close();DataTable GetSchemaTable();bool NextResult();bool Read();Dispose();}Наконец, интерфейс
расширяетIDataReader. В интерфейсеIDataRecordопределено много членов, которые позволяют извлекать из потока строго типизированное значение, а не приводить к нужному типу экземплярIDataRecord, полученный из перегруженного метода индексатора объекта чтения данных. Вот определение интерфейсаSystem.Object:IDataRecordpublic interface IDataRecord{int FieldCount { get; }object this[ int i ] { get; }object this[ string name ] { get; }bool GetBoolean(int i);byte GetByte(int i);long GetBytes(int i, long fieldOffset, byte[] buffer,int bufferoffset, int length);char GetChar(int i);long GetChars(int i, long fieldoffset, char[] buffer,int bufferoffset, int length);IDataReader GetData(int i);string GetDataTypeName(int i);DateTime GetDateTime(int i);Decimal GetDecimal(int i);double GetDouble(int i);Type GetFieldType(int i);float GetFloat(int i);Guid GetGuid(int i);short GetInt16(int i);int GetInt32(int i);long GetInt64(int i);string GetName(int i);int GetOrdinal(string name);string GetString(int i);object GetValue(int i);int GetValues(object[] values);bool IsDBNull(int i);}На заметку! Метод
можно применять для программного выяснения, установлено ли указанное поле вIDataReader.IsDBNull(), прежде чем пытаться получить значение из объекта чтения данных (во избежание генерации исключения во время выполнения). Также вспомните, что язык C# поддерживает типы данных, допускающиеnull(см. главу 4), идеально подходящие для взаимодействия со столбцами, которые могут иметь значениеnullв таблице базы данных.nullАбстрагирование поставщиков данных с использованием интерфейсов
К настоящему моменту вы должны лучше понимать общую функциональность, присущую всем поставщикам данных .NET Core. Вспомните, что хотя точные имена реализуемых типов будут отличаться между поставщиками данных, в коде такие типы применяются в схожей манере — в том и заключается преимущество полиморфизма на основе интерфейсов. Скажем, если определить метод, который принимает параметр
, то ему можно передавать любой объект подключения ADO.NET:IDbConnectionpublic static void OpenConnection(IDbConnection cn){<b> // Открыть входное подключение для вызывающего кода.</b>connection.Open();}На заметку! Использовать интерфейсы вовсе не обязательно; аналогичного уровня абстракции можно достичь путем применения абстрактных базовых классов (таких как
) в качестве параметров или возвращаемых значений. Однако использование интерфейсов вместо базовых классов является общепринятой практикой.DbConnectionТо же самое справедливо для возвращаемых значений. Создайте новый проект консольного приложения .NET Core по имени
. Добавьте в проект перечисленные ниже пакеты NuGet (пакетMyConnectionFactoryдействителен только в Windows):OleDbMicrosoft.Data.SqlClientSystem.Data.CommonSystem.Data.OdbcSystem.Data.OleDbДалее добавьте в проект новый файл по имени
со следующим кодом:DataProviderEnum.cs