Net framework data provider for sql server настройка

Обновлено: 07.07.2024

В целях борьбы со склерозом, и чтобы не бегать и не искать документацию, когда в очередной раз требуется подключиться к какой-нибудь базе данных, собрал в этом посте строки подключений к различным источникам данных, которые я чаще всего использую.

Строка подключения:

Server = ip_адрес_или_имя_сервера : номер_порта_сервера; Database=имя_базы; UID = имя_пользователя; PWD=пароль;
  • MaxPoolSize, MinPoolSize - максимальный и минимальный размер пула соединений с БД
  • Pooling=false - отключить обьединение подключений в пул (по умолчанию - true)
  • Connection Lifetime - количество секунд, которое каждое соединение удерживается в пуле подключений.
Provider=DB2OLEDB; Network Transport Library = TCPIP; Network Address=xxx.xxx.xxx.xxx; Initial Catalog = имя_каталога; Package Collection = имя_коллекции; Default Schema = имя_схемы; User Password = пароль;

Строка подключения:

User = логин; Password = пароль; Database = MyDatabase.fdb; DataSource=localhost; Port=3050; Dialect=3; Charset=NONE; Role=; Connection lifetime = 15; Pooling=true; MinPoolSize=0; MaxPoolSize=50; Packet Size=8192; ServerType=0;
  • 0 - Classic или Super Server
  • 1 - Embedded Server
Driver = Firebird/InterBase(r) driver; Uid=логин; Pwd=пароль; DbName = путь_к_fdb_файлу;
Server =адрес_сервера; Database = имя_базы; Uid = логин; Pwd = пароль;
  • Port - номер порта для подключения, если = -1, значит используется протокол named papes.

Строка подключения:

Data Source = имя/адрес_сервера; Initial Catalog = имя_БД; User Password = пароль;

Строка подключения:

Provider = SQLNCLI10; Server = имя/адрес_сервера; Database = имя_БД; Uid = логин; Pwd = пароль;

Microsoft Jet OLE DB 4.0

Строка подключения:

Provider = Microsoft.Jet.OLEDB.4.0; Data Source =путь_к_папке; Extended Properties = dBASE IV; User Password=;

Если база защищена паролем, ID и Password нужно поменять.

Строка подключения:

Provider = Microsoft.Jet.OLEDB.4.0; Data Source=путь_к_папке; Extended Properties = dBASE IV; User Password=;

Строка подключения:

  • UseUTF16Encoding=True - использовать кодировку UTF16
  • Password - пароль для соединения
  • Read Only = true - соединение только для чтения


Microsoft Jet OLE DB 4.0

Строка подключения:

Provider = Microsoft.Jet.OLEDB.4.0; Data Source=C:\mydb.mdb; User Password=;

Для расположенной на расшаренном ресурсе базы:

Provider = Microsoft.Jet.OLEDB.4.0; Data Source = \\хост\путь_до_базы\mydb.mdb; User Password=;

Строка подключения:

Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\mydb.mdb; User Password=;

Access 2007


ACE OLEDB 12.0

Строка подключения:

Provider = Microsoft.ACE.OLEDB.12.0; Data Source = C:\myfile.accdb; Persist Security Info=False;

Если установлен пароль:

Provider = Microsoft.ACE.OLEDB.12.0; Data Source = C:\myfile.accdb; Jet OLEDB:Database Password = MyDbPassword;

Строка подключения:

Provider = Microsoft.ACE.OLEDB.12.0; Data Source = C:\myfile.accdb; Persist Security Info = False;


Другие источники данных:

Excel 97-2003

Microsoft Jet OLE DB 4.0

Строка подключения:

Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:\myfile.xls; Extended Properties="Excel 8.0; HDR=Yes; IMEX=1";

HDR=Yes - указывает, что первая строка содержит имена столбцов, а не данные
IMEX=1 - указывает драйверу читать все данные как текстовые

Предварительные требования

Включение Always Encrypted для запросов приложений

Самым простым способом включения шифрования параметров и расшифровки результатов запросов к зашифрованным столбцам является установка для ключевого слова строки подключения "Параметр шифрования столбца" значения Включено.

Ниже приведен пример строки подключения, включающий постоянное шифрование.

Далее приведен эквивалент примера с использованием свойства SqlConnectionStringBuilder.ColumnEncryptionSetting.

Постоянное шифрование также можно включить для отдельных запросов. См. раздел Управление влиянием постоянного шифрования на производительность ниже. Включения функции Always Encrypted недостаточно для успешного шифрования или расшифровки. Необходимо также проверить выполнение следующих условий:

  • Приложение имеет разрешения VIEW ANY COLUMN MASTER KEY DEFINITION и VIEW ANY COLUMN ENCRYPTION KEY DEFINITION для базы данных, необходимые для доступа к метаданным о ключах постоянного шифрования в базе данных. Для дополнительных сведений см. страницу о разрешениях в статье "Always Encrypted (ядро СУБД)".
  • Приложение может получить доступ к главному ключу столбца, который защищает ключи шифрования столбцов, шифрующие запрашиваемые столбцы базы данных.

Включение Always Encrypted с безопасными анклавами

Общие сведения о роли клиентского драйвера в вычислениях анклава и аттестации анклава см. в статье Разработка приложений с помощью Always Encrypted с безопасными анклавами.

Включите Always Encrypted для запросов приложения, как описано в предыдущем разделе.

Интегрируйте пакет NuGet Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders в приложение. NuGet — это библиотека поставщиков анклавов, которая реализует логику на стороне клиента для протокола аттестации, а также для установки безопасного канала с безопасным анклавом.

Измените конфигурацию приложения (например, в файле web.config или app.config), чтобы определить сопоставление типа анклава, настроенного для базы данных, и поставщика анклава.

  1. При использовании SQL Server и службы защиты узла (HGS) необходимо соотнести тип анклава VBS с классом Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders.HostGuardianServiceEnclaveProvider из пакета NuGet.
  2. При использовании База данных SQL Azure и службы "Аттестация Microsoft Azure" необходимо соотнести тип анклава SGX с классом Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders.AzureAttestationEnclaveProvider из пакета NuGet.

В строке подключения к базе данных задайте для ключевого слова Enclave Attestation URL URL-адрес аттестации (конечная точка службы аттестации). Необходимо получить URL-адрес аттестации для имеющейся среды у администратора службы аттестации.

  1. Если вы используете SQL Server и службу защитника узлов (HGS), см. сведения в разделе об определении и совместном использовании URL-адреса аттестации HGS.
  2. Если вы используете База данных SQL Azure и Аттестацию Microsoft Azure, см. сведения об определении URL-адреса аттестации для политики аттестации.

Получение и изменение данных в зашифрованных столбцах

В приведенной ниже таблице описывается поведение запросов в зависимости от того, включено постоянное шифрование или нет.

Характеристика запроса Постоянное шифрование включено, и приложение может получать доступ к ключам и метаданным ключей Функция Always Encrypted включена, и приложение не может получать доступ к ключам и метаданным ключей Постоянное шифрование отключено
Запросы с параметрами, предназначенными для зашифрованных столбцов. Значения параметров прозрачно шифруются. Error Error
Запросы, получающие данные из зашифрованных столбцов, без параметров, предназначенных для зашифрованных столбцов. Результаты из зашифрованных столбцов прозрачно расшифровываются. Приложение получает значения типов данных .NET в виде открытого текста, которые соответствуют типам SQL Server, настроенным для зашифрованных столбцов. Error Результаты из зашифрованных столбцов не расшифровываются. Приложение получает зашифрованные значения в виде массивов байтов (byte[]).

В следующих примерах показано получение и изменение данных в зашифрованных столбцах. В примерах предполагается использование целевой таблицы с приведенной ниже схемой. Столбцы SSN и BirthDate зашифрованы.

Пример вставки данных

В этом примере показана вставка строки в таблицу Patients. Следует отметить следующее.

Пример получения данных в виде открытого текста

В следующем примере показана фильтрация данных на основе зашифрованных значений и получение данных в виде открытого текста из зашифрованных столбцов. Следует отметить следующее.

Запросы могут выполнять сравнение на равенство для столбцов, если они шифруются с помощью детерминированного шифрования. Дополнительные сведения см. в разделе Выбор детерминированного или случайного шифрования.

Пример получения зашифрованных данных

Если постоянное шифрование не включено, запрос может получать данные из зашифрованных столбцов, пока для него не будут указаны параметры, предназначенные для зашифрованных столбцов.

В следующем примере показано извлечение двоичных зашифрованных данных из зашифрованных столбцов. Следует отметить следующее.

  • Так как постоянное шифрование не включено в строке подключения, запрос будет возвращать зашифрованные значения SSN и BirthD в виде байтовых массивов (программа преобразует значения в строки).
  • Запрос, получающий данные из зашифрованных столбцов с отключенным постоянным шифрованием, может иметь параметры при условии, что ни один из параметров не предназначен для зашифрованного столбца. Приведенный выше запрос выполняет фильтрацию по LastName, который не зашифрован в базе данных. Запрос, отфильтрованный по SSN или BirthDate, завершится ошибкой.

Как избежать распространенных проблем при запросе зашифрованных столбцов

Ошибки преобразования неподдерживаемых типов данных

Постоянное шифрование поддерживает несколько преобразований для зашифрованных типов данных. Подробный список поддерживаемых преобразований типов см. в статье Always Encrypted. Чтобы избежать ошибок при преобразовании типов данных, сделайте следующее:

Ошибки, возникающие из-за передачи значений в виде открытого текста, а не в зашифрованном виде

Любое значение, предназначенное для зашифрованного столбца, должно быть зашифровано внутри приложения. Попытка вставки, изменения или фильтрации по значению в виде открытого текста в зашифрованном столбце приведет к возникновению ошибки, подобной следующей:

Чтобы избежать таких ошибок, убедитесь, что:

  • функция Always Encrypted включена для запросов приложений, предназначенных для зашифрованных столбцов (для строки подключения или в отдельном объекте SqlCommand для конкретного запроса);
  • для отправки данных, предназначенных для зашифрованных столбцов, используется параметр SqlParameter. В примере ниже показан запрос, который вместо передачи литерала внутри объекта SqlParameter неправильно фильтрует по литералу или константе в зашифрованном столбце (SSN).

Работа с хранилищами главных ключей столбцов

Процедура получения ключа шифрования столбца:

  • Имя поставщика хранилища ключей, который инкапсулирует хранилище ключей, содержащее главный ключ столбца.
  • Путь к ключу, указывающий положение главного ключа столбца в хранилище ключей.

Сведения о ключе шифрования столбца включают в себя следующее:

  • Зашифрованное значение ключа шифрования столбца.
  • Имя алгоритма, который использовался для шифрования ключа шифрования столбца.

Использование встроенных поставщиков хранилища главных ключей столбцов

Для использования этих поставщиков не требуется изменять код приложения, однако необходимо учесть следующие моменты.

  • Вы (или ваш администратор баз данных) должны проверить правильность имени поставщика, настроенного в метаданных главного ключа столбца, и убедиться, что путь к ключу главного ключа столбца соответствует формату пути к ключу, который является допустимым для данного поставщика. Для настройки ключей рекомендуется использовать средство, такое как среда SQL Server Management Studio, которое при выполнении инструкции CREATE COLUMN MASTER KEY (Transact-SQL) автоматически создает допустимые имена поставщиков и пути к ключам. Дополнительные сведения см. в разделах Configuring Always Encrypted using SQL Server Management Studio (Настройка Always Encrypted с помощью среды SQL Server Management Studio ) и Настройка постоянного шифрования с помощью PowerShell.
  • Убедитесь, что приложение может получить доступ к ключу в хранилище ключей. Для этого может потребоваться предоставить приложению доступ к ключу или хранилищу ключей (в зависимости от хранилища ключей) или выполнить другие действия по настройке конкретного хранилища ключей. Например, для доступа к хранилищу, реализующему CNG или CAPI (например, к аппаратному модулю безопасности), на компьютере с приложением необходимо установить библиотеку, реализующую CNG или CAPI для хранилища. Дополнительные сведения см. в разделе Создание и хранение главных ключей столбцов для Always Encrypted.

Использование поставщика хранилища ключей Azure

Реализация настраиваемого поставщика хранилища главных ключей столбцов

Чтобы сохранить главные ключи столбцов в хранилище ключей, не поддерживаемом существующим поставщиком, можно реализовать настраиваемый поставщик, расширив класс SqlColumnEncryptionCngProvider и зарегистрировав поставщик с помощью метода SqlConnection.RegisterColumnEncryptionKeyStoreProviders .

Использование поставщиков хранилищ главных ключей столбцов для программной подготовки ключей

Управление влиянием постоянного шифрования на производительность

Поскольку постоянное шифрование является технологией шифрования на стороне клиента, значительное влияние на производительность происходит на стороне клиента, а не в базе данных. Помимо затрат на операции шифрования и расшифровки существуют и другие источники снижения производительности на стороне клиента:

  • Дополнительные обращения к базе данных для получения метаданных для параметров запроса.
  • Вызовы хранилища главных ключей столбцов для доступа к главному ключу столбца.

Управление обращениями для получения метаданных для параметров запроса

Кэширование метаданных запроса

Задание постоянного шифрования на уровне запроса

Для управления влиянием процесса получения метаданных шифрования для параметризованных запросов на производительность можно включить постоянное шифрование для отдельных запросов, а не настраивать его для соединения. Таким образом, это гарантирует, что sys.sp_describe_parameter_encryption вызывается только для запросов, которые точно имеют параметры, предназначенные для зашифрованных столбцов. Обратите внимание, что в этом случае снижается прозрачность шифрования: при изменении свойств шифрования столбцов базы данных может потребоваться изменить код приложения в соответствии с изменениями схемы.

Для управления поведением функции Always Encrypted в отдельных запросах необходимо использовать этот конструктор SqlCommand и SqlCommandColumnEncryptionSetting. Ниже приведены некоторые полезные рекомендации.

  • Если большинство запросов, отправляемых клиентским приложением через подключение к базе данных, получает доступ к зашифрованным столбцам:
    • Задайте для ключевого слова строки подключения Параметр шифрования столбца значение Включено.
    • Задайте SqlCommandColumnEncryptionSetting.Disabled для отдельных запросов, которые не обращаются к зашифрованным столбцам. Будет отключена возможность вызова sys.sp_describe_parameter_encryption и расшифровки всех значений в наборе результатов.
    • Задайте SqlCommandColumnEncryptionSetting.ResultSet для отдельных запросов, которые не имеют параметров, требующих шифрования, но получают данные из зашифрованных столбцов. Будет отключена возможность вызова sys.sp_describe_parameter_encryption и шифрования параметров. Запрос сможет расшифровывать результаты из столбцов шифрования.
    • Задайте для ключевого слова строки подключения Параметр шифрования столбца значение Отключено.
    • Задайте SqlCommandColumnEncryptionSetting.Enabled для отдельных запросов, имеющих параметры, которые требуется зашифровать. Будет включена возможность вызова sys.sp_describe_parameter_encryption и расшифровки результатов запроса, полученных из зашифрованных столбцов.
    • Задайте SqlCommandColumnEncryptionSetting.ResultSet для запросов, которые не имеют параметров, требующих шифрования, но получают данные из зашифрованных столбцов. Будет отключена возможность вызова sys.sp_describe_parameter_encryption и шифрования параметров. Запрос сможет расшифровывать результаты из столбцов шифрования.

    В следующем примере постоянное шифрование отключено для подключения к базе данных. Запрос, выполняемый приложением, имеет параметр, предназначенный для незашифрованного столбца LastName. Запрос получает данные из зашифрованных столбцов SSN и BirthDate. В этом случае вызывать sys.sp_describe_parameter_encryption для получения метаданных шифрования не требуется. Однако необходимо включить расшифровку результатов запроса, чтобы приложение могло получать значения в виде обычного текста из двух зашифрованных столбцов. Для этого используется параметр SqlCommandColumnEncryptionSetting.ResultSet.

    Кэширование ключа шифрования столбца

    Включение дополнительной защиты для скомпрометированного SQL Server

    Принудительное шифрование параметров

    Хотя использование свойства SqlParameter.ForceColumnEncryption помогает повысить безопасность, оно также снижает прозрачность шифрования для клиентского приложения. Если вы обновляете схему базы данных для изменения набора зашифрованных столбцов, вам может потребоваться изменить и само приложение.

    В следующем примере кода показано, как с помощью свойства SqlParameter.ForceColumnEncryption предотвратить отправку номеров социального страхования в базу данных в формате открытого текста.

    Настройка доверенных путей для главных ключей столбцов

    Несмотря на то, что установка доверенных путей повышает безопасность приложения, вам потребуется изменять код или (и) конфигурацию приложения при каждой смене главного ключа столбца (или при изменении пути к главному ключу столбца).

    В следующем примере показано, как настраивать доверенные пути к главному ключу столбца:

    Копирование зашифрованных данных с помощью SqlBulkCopy

    С помощью SqlBulkCopy можно скопировать данные, которые уже зашифрованы и хранятся в одной таблице, в другую таблицу, не расшифровывая при этом данные. Для этого выполните указанные далее действия.

    Ниже приведен пример копирования данных из одной таблицы в другую. Предполагается, что столбцы SSN и BirthDate зашифрованы.

    image

    Жил-был проект на EF 6 с СУБД MSSQL. И появилась необходимость добавить возможность его работы с СУБД PostgreSQL. Проблем здесь мы не ожидали, ведь есть большое количество статей на эту тему, и на форумах можно найти обсуждение похожих задач. Однако, на деле не все оказалось так просто, и в этой статье мы расскажем об этом опыте, о проблемах, с которыми мы столкнулись в ходе интеграции нового провайдера, и про выбранное нами решение.

    Вводная

    У нас коробочный продукт, и он имеет уже устоявшуюся структуру. Изначально он был настроен на работу с одной СУБД — MSSQL. Проект имеет слой доступа к данным с реализацией EF 6 (подход Code First). С миграциями работаем через EF 6 Migrations. Миграции создаются в ручном режиме. Первичная установка БД происходит из консольного приложения с инициализацией контекста по строке подключения, передаваемого в качестве аргумента:


    При этом инфраструктура EF и доменная область описаны в другом проекте, который подключен к консольному приложению в качестве библиотеки. Конструктор контекста в проекте инфраструктуры выглядит так:

    Первый запуск

    Первое, что мы сделали, — подключили к проекту два пакета через nuget: Npgsql и EntityFramework6.Npgsql.

    А также прописали в App.config нашего консольного приложения настройки для Postgres.

    В секции entityFramework указали в качестве фабрики соединения по умолчанию фабрику postgres:


    В секции DbProviderFactories зарегистрировали фабрику нового провайдера:


    И сразу в лоб попробовали инициализировать БД, указав в строке подключения адрес сервера Postgres и учетные данные админа сервера. Получилась такая строка:

    “Server = localhost; DataBase = TestPostgresDB; Integrated Security = false; User password = pa$$w0rd”

    Как и ожидалось, благодаря ручному режиму EF Migrations, инициализация не прошла, и возникла ошибка несоответствия снимка БД текущей модели. Чтобы обойти создание первичной миграции с новым провайдером и протестировать инициализацию БД на Postgres, мы скорректировали немного конфигурацию нашей инфраструктуры.

    Во-первых, мы включили “автомиграции” — полезная опция, если изменения доменных моделей и инфраструктуры EF в команде ведет один разработчик:


    Во-вторых, мы указали нового провайдера в переопределенном методе InitializeDatabase унаследованного класса CreateDatabaseIfNotExists, где у нас запускаются миграции:


    Далее, мы снова запустили наше консольное приложение с той же строкой подключения в качестве аргумента. На этот раз инициализация контекста прошла без ошибок, и наши доменные модели благополучно легли в новую БД на Postgres. В новой базе данных появилась табличка “__MigrationHistory”, в которой лежала единственная запись о первой автоматически созданной миграции.

    Подведем подытог: мы без особых проблем смогли подключить нового провайдера к существующему проекту, но при этом изменили настройки механизма миграций.

    Включаем ручной режим миграций

    Как уже упомянуто выше, при включенном режиме автоматических миграций вы лишаете свою команду параллельной разработки в области домена и области доступа к данным. Для нас такой вариант был неприемлем. Поэтому нам было необходимо настроить ручной режим миграций в проекте.

    Сначала мы вернули полю AutomaticMigrationsEnabled значение false. Затем надо было разобраться с созданием новых миграций. Мы понимали, что миграции для разных СУБД, как минимум, должны храниться в разных папках проекта. Поэтому мы решили создать новую папку под миграции Postgres в проекте инфраструктуры под названием PostgresMigrations (папку с миграциями MsSql, для наглядности, мы переименовали в MsSqlMigrations), и скопировали в нее конфигурационный файл миграций MsSql. При этом, все существующие миграции MsSql мы не копировали в PostgresSql. Во-первых, потому, что все они содержат снимок конфигурации под провайдера MsSql и, соответственно, мы их не сможем использовать на новом СУБД. Во-вторых, для нового СУБД нам не важна история изменений, и мы можем обойтись последним снимком состояния доменных моделей.

    Мы посчитали, что все готово для формирования первой миграции на Postgres. Удалили БД, созданную при инициализации контекста с включенным режимом автоматических миграций. И, руководствуясь тем, что для первой миграции нужно сформировать физическую БД на основе текущего состояния доменных моделей, мы радостно забили команду Update-Database в Package Manager Console, указав только параметр строки подключения. В итоге мы получили ошибку, связанную с подключением к СУБД.

    Дополнительно изучив принцип работы команды Update-Database, мы сделали следующее:

      добавили в настройки конфигурации миграций следующий код:

    Update-Database -ProjectName «Project.Infrastructure» -ConfigurationTypeName Project.Infrastructure.PostgresMigrations.Configuration -ConnectionString «Server=localhost; DataBase=TestPostgresDB; Integrated Security=false; User password=pa$$w0rd» -ConnectionProviderName «Npgsql»
    После выполнения этой команды мы смогли выполнить команду Add-Migration с аналогичными параметрами, назвав первую миграцию InitialCreate:
    Add-Migration -Name «InitialCreate» -ProjectName «CrossTech.DSS.Infrastructure» -ConfigurationTypeName CrossTech.DSS.Infrastructure.PostgresMigrations.Configuration -ConnectionString «Server=localhost; DataBase=TestPostgresDB; Integrated Security=false; User password=pa$$w0rd» -ConnectionProviderName «Npgsql»

    В папке PostgresMigrations появился новый файл: 2017010120705068_InitialCreate.cs

    Затем мы удалили БД, созданную после выполнения команды Update-Database, и запустили наше консольное приложение со строкой подключения, указанной выше в качестве аргумента. И вот мы получили БД уже на основе миграции, созданной вручную.

    Подведем подытог: мы смогли минимальными усилиями добавить первую миграцию для провайдера Postgres и инициализировать контекст через консольное приложение, получив на выходе новую БД, в которую легли изменения из нашей первой ручной миграции.

    Переключение между провайдерами

    У нас оставался один незакрытый вопрос: как настроить инициализацию контекста таким образом, чтобы можно было обращаться к конкретному СУБД в runtime?

    Задача состояла в том, чтобы на этапе инициализации контекста можно было выбрать ту или иную целевую БД нужного провайдера. В результате многократных попыток настроить это переключение, мы пришли к решению, которое выглядит так.

    В консольном приложении проекта в app.config (а если не использовать app.config, то machine.config) добавляем новую строку подключения с указанием провайдера и названия соединения, а в конструктор контекста «прокидываем» название соединения вместо строки подключения. При этом, саму строку подключения связываем с контекстом через синглтон инстанции DbConfiguration. В качестве параметра передаем инстанцию унаследованного класса от DbConfiguration.

    Получившийся унаследованный класс DbConfiguration:


    И сама инициализация контекста теперь выглядит так:


    И кто следил внимательно, тот наверняка заметил, что нам оставалось сделать еще одно изменение в коде. Это определение целевой БД во время инициализации БД, которая происходит в описанном ранее методе InitializeDatabase.

    Мы добавили простой switch для определения конфигурации миграций конкретного провайдера:


    А сам конструктор контекста стал выглядеть так:


    Далее, мы запустили консольное приложение и указали в качестве провайдера СУБД в параметре приложение MsSql. Аргументы приложения мы задали следующие:

    «MsSqlDbConnection» «Server=localhost\SQLEXPRESS; Database=TestMsSqlDB; User password=pa$$w0rd» «System.Data.SqlClient»

    База данных MsSql была создана без ошибок.

    Затем мы указали аргументы приложения:

    «PostgresDbConnection» «Server=localhost; DataBase=TestPostgresDB; Integrated Security=false; User password=pa$$w0rd» «Npgsql»

    База данных Postgres была создана также без ошибок.

    Итак, еще один подытог — для того, чтобы EF мог инициализировать контекст БД для конкретного провайдера, в runtime необходимо:

    • “указать” механизму миграций на этого провайдера
    • сконфигурировать строки подключения к СУБД до инициализации контекста

    Работаем с миграциями двух СУБД в команде

    Как мы увидели, самое интересное начинается после появления новых изменений в домене. Вам необходимо для двух СУБД генерировать миграции с учетом конкретного провайдера.

    Так, для MSSQL Server нужно выполнить последовательные команды (для Postgres описаны команды выше, при создании первой миграции):

      обновление БД в соответствии с последним снимком

    Update-Database -ProjectName «Project.Infrastructure» -ConfigurationTypeName Project.Infrastructure.MsSqlMigrations.Configuration -ConnectionString «Server=localhost; DataBase=TestMsSqlDB; Integrated Security=false; User password=pa$$w0rd» -ConnectionProviderName «System.Data.SqlClient»
    Add-Migration -Name «SomeMigrationName» -ProjectName «Project.Infrastructure» -ConfigurationTypeName Project.Infrastructure.MsSqlMigrations.Configuration -ConnectionString «Server=localhost; DataBase=TestMsSqlDB; Integrated Security=false; User password=pa$$w0rd» -ConnectionProviderName «System.Data.SqlClient»

    При этом, решение конфликтов по миграциям EF в команде сводится к выставлению приоритетов значимости изменений того или иного разработчика. И чьи изменения выше по приоритету, те и должны первыми заливать их в git, а остальным разработчикам по оговоренной иерархии нужно сделать следующее:

    1. удалить созданные локальные миграции
    2. подтянуть к себе изменения из репозитория, куда остальные коллеги с высоким приоритетом уже влили свои миграции
    3. создать локальную миграцию и залить получившиеся изменения обратно в git

    В заключение

    Работать с несколькими СУБД, применяя EF6 в связке с EF Migrations, реально, но в этом варианте ребята из Microsoft не учли возможность параллельной работы команды с использованием систем контроля версий.

    Есть множество альтернативных EF Migrations решений на рынке (как платных, так и бесплатных): DbUp, RoundhousE, ThinkingHome.Migrator, FluentMigrator и т.д. И, судя по отзывам, они больше по душе разработчикам, нежели EF Migrations.

    К счастью, у нас появилась возможность сделать некий апгрейд в нашем проекте. И в ближайшее время мы будем переходить на EF Core. Мы взвесили все «за» и «против» механизма EF Core Migrations и пришли к выводу, что нам удобнее будет работать со сторонним решением, а именно Fluent Migrator.

    Надеемся, вам был интересен наш опыт. Готовы принять замечания и ответить на вопросы, велкам!

    Подключение и создание базы данных в Entity Framework Core

    Entity Framework Core в ASP.NET Core

    Для взаимодействия с MS SQL Server через Entity Framework необходим пакет Microsoft.EntityFrameworkCore.SqlServer . По умолчанию он отсутствует в проекте, поэтому его надо добавить, например, через пакетный менеджер Nuget:

    Entity Framework Core в ASP.NET Core

    Далее добавим в проект класс модели, с которой мы будем работать. По умолчанию в проекте уже есть предназначенная для моделей папка Models. Определим в этой папке определим новый класс User:

    Эта модель представляет те объекты, которые будут храниться в базе данных.

    Чтобы взаимодействовать с базой данных через Entity Framework нам нужен контекст данных - класс, унаследованный от класса Microsoft.EntityFrameworkCore.DbContext . Поэтому добавим в папку Models новый класс, который назовем ApplicationContext (название класса контекста произвольное):

    Свойство DbSet представляет собой коллекцию объектов, которая сопоставляется с определенной таблицей в базе данных. При этом по умолчанию название свойства должно соответствовать множественному числу названию модели в соответствии с правилами английского языка. То есть User - название класса модели представляет единственное число, а Users - множественное число.

    Через параметр options в конструктор контекста данных будут передаваться настройки контекста.

    В конструкторе с помощью вызова Database.EnsureCreated() по определению моделей будет создаваться база данных (если она отсутствует).

    Чтобы подключаться к базе данных, нам надо задать параметры подключения. Для этого изменим файл appsettings.json , добавив в него определение строки подключения:

    В данном случае мы будем использовать упрощенный движок базы данных LocalDB, который представляет легковесную версию SQL Server Express, предназначенную специально для разработки приложений.

    И последним шагом в настройке проекта является изменение файла Startup.cs . В нем нам надо изменить метод ConfigureServices() :

    Добавление контекста данных в виде сервиса позволит затем получать его в конструкторе контроллера через механизм внедрения зависимостей.

    Читайте также: