Функции Azure, Entity Framework и Oracle DB - основные ошибки POC - PullRequest
0 голосов
/ 17 мая 2018

У меня много проблем с получением базовых проверочных концепций, при которых я обращаюсь к базе данных Oracle (11g) через функции Azure через Entity Framework (6.2).

Предварительные условия:Установлен ODT для Visual Studio 2017, а также CLI / Core Tools функций Azure.Все, что упомянуто ниже, полностью выполняется через Visual Studio 2017, а не через портал Azure.

Take 1:

Создан новый проект с шаблоном функций Azure.

Установленные пакеты NuGet EntityFramework (6.2.0), Oracle.ManagedDataAccess (12.2.1100) и Oracle.ManagedDataAccess.EntityFramework (12.2.1100).Примечание. При установке пакетов NuGet в проекты с использованием шаблона функций Azure пакеты добавляются в разделе Зависимости -> NuGet, а не в разделе Ссылки.

В проект добавлена ​​модель данных объекта ADO.NET.

Проблема: После установки строки подключения, выбор Entity Framework 6.x недоступен со следующим сообщением об ошибке:

Поставщик базы данных Entity Framework, совместимый с последней версиейНе удалось найти Entity Framework для вашего подключения к данным.Если вы уже установили совместимого поставщика, убедитесь, что вы перестроили свой проект, прежде чем выполнять это действие.В противном случае выйдите из этого мастера, установите совместимый поставщик и перестройте свой проект до выполнения этого действия.

В качестве самого простого обходного пути я попытался просто использовать EF5, но он выдает исключениепри создании модели БД (после выбора объектов для включения в модель, включая некоторые хранимые процедуры).

Take 2:

Создан проект и установлены пакеты NuGet, как указано выше.

Создан проект библиотеки классов для облегчения взаимодействия с Oracle.

Установлены те же пакеты NuGet, что и выше в проекте библиотеки классов.

Добавлена ​​модель данных сущности ADO.NET впроект библиотеки классов и добавление некоторых объектов базы данных в модель базы данных.Кроме того, в модель добавлен пользовательский конструктор для конкретной строки подключения, поскольку управление строками подключения в функциях Azure было отдельным набором головной боли, с которой я буду иметь дело позже.

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

public static string NameByEmpNo(int empNo)
{
    string result;
    MyEntities entities = new MyEntities("metadata=res://*/MyEntities.csdl|res://*/MyEntities.ssdl|res://*/MyEntities.msl;provider=Oracle.ManagedDataAccess.Client;provider connection string='DATA SOURCE=127.0.0.1:1521/ORCL;PASSWORD=tiger;USER ID=SCOTT'");
    ObjectParameter name = new ObjectParameter("o_empname", typeof(string));
    entities.GET_EMP_NAME_PROC(empNo, name);
    result = (string)name.Value;
    return result;
}

Добавлена ​​ссылка на библиотеку классов в проекте функций Azure.

Добавлена ​​функция, которая вызывает NameByEmpNo:

    [FunctionName("GetNameByEmpNo")]
    public static async Task<HttpResponseMessage> GetNameByEmpNo([HttpTrigger(AuthorizationLevel.Function, "get", Route = null)]HttpRequestMessage req, TraceWriter log)
    {
        int empNo = Int32.Parse(req.GetQueryNameValuePairs()
            .FirstOrDefault(q => string.Compare(q.Key, "empno", true) == 0)
            .Value);
        string empName = ScottAccess.NameByEmpNo(empNo);
        return req.CreateResponse(HttpStatusCode.OK, "Employee name: " + empName);
    }

Проблема: Во время выполнения вызов функции завершается неудачно с этим сообщением об ошибке:

Исключительная ситуация при выполнении функции: GetNameByEmpNo -> Поставщик ADO.NET с инвариантным именем 'Oracle.ManagedDataAccess.Client 'либо не зарегистрирован в файле конфигурации компьютера или приложения, либо не может быть загружен.Смотрите внутреннее исключение для деталей.-> Невозможно найти запрошенный поставщик данных .Net Framework.Возможно, он не установлен.

Информация о бонусе: Моя библиотека классов отлично работает при вызове через консольное приложение.Кроме того, мое приложение Azure Functions прекрасно работает при вызове функций, которые не используют мою библиотеку классов ...

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

1 Ответ

0 голосов
/ 18 декабря 2018

Entity Framework в функциях Azure по умолчанию предоставляет провайдерам System.Data.SqlClient, поэтому соединения SQL будут работать без каких-либо изменений конфигурации, но это означает, что вы должны сделать что-то особенное для соединений Oracle.Кажется, проблема связана с значениями конфигурации, которые, как предполагает библиотека Oracle.ManagedDataAccess.Client, доступны в файле App.Config или Web.Config в проекте, которые вставляются при установке пакета Nuget Oracle.ManagedDataAcess.EntityFramework.Функции Azure не имеют файлов конфигурации, и я не смог найти способа указать поставщика Oracle в файлах json настроек.

Я нашел решение в этой публикации

Предлагается обойти этот механизм и создать DbConfiguration для Oracle, а затем с помощью DbConfigurationType сообщить DbContext, какую конфигурацию вы используете.

public class OracleDbConfiguration : DbConfiguration
{
    public OracleDbConfiguration()
    {
        SetDefaultConnectionFactory(new OracleConnectionFactory());
        SetProviderServices("Oracle.ManagedDataAccess.Client", EFOracleProviderServices.Instance);
        SetProviderFactory("Oracle.ManagedDataAccess.Client", new OracleClientFactory());
    }
}

[DbConfigurationType(typeof(OracleDbConfiguration))]
public partial class MyEntities : IGISContext
{
    //Expose Connection String Constructor
    public MyEntities(string connectionString, int commandTimeoutInSeconds = 30) : base(connectionString)
    {
        this.Database.CommandTimeout = commandTimeoutInSeconds;
    }
}

Примечание: я использовал сначала базу данных EF 6 для генерациимой EDMX;MyEntities здесь является частичным классом для предоставления конструктора, который принимает строку соединения.

Соединение оракула будет использовать указанный класс DbConfiguration, и любые соединения базы данных SQL будут продолжать работать с использованием значений по умолчанию.

Мое решение использует пакеты Nuget:

  • EntityFramework 6.2.0
  • Oracle.ManagedDataAccess 12.2.1100
  • Oracle.ManagedDataAccess.EntityFramework 12.2.1100
...