visual-studio - Azure Functions、 Entity Framework 和 Oracle DB - 基本 POC 失败

标签 visual-studio entity-framework oracle11g azure-functions ef-database-first

我在进行基本概念验证时遇到了很多困难,其中我通过 Entity Framework (6.2) 通过 Azure Functions 访问 Oracle DB (11g)。

先决条件: 已安装 ODT For Visual Studio 2017 以及 Azure Functions CLI/Core Tools。下面提到的所有内容完全通过 Visual Studio 2017 完成,而不是通过 Azure 门户。

取 1:

使用 Azure Functions 模板创建了一个新项目。

已安装的 NuGet 包 EntityFramework (6.2.0)、Oracle.ManagedDataAccess (12.2.1100) 和 Oracle.ManagedDataAccess.EntityFramework (12.2.1100)。注意:使用 Azure Functions 模板在项目中安装 NuGet 包时,这些包将添加到“依赖项”->“NuGet”下,而不是“引用”下。

向项目添加了 ADO.NET 实体数据模型。

问题:设置连接字符串后,无法选择 Entity Framework 6.x,并出现以下错误消息:

An Entity Framework database provider compatible with the latest version of Entity Framework could not be found for your data connection. If you have already installed a compatible provider, ensure you have rebuilt your project before performing this action. Otherwise, exit this wizard, install a comaptible provider, and rebuild your project befre performing this action.

作为最简单的解决方法,我尝试继续使用 EF5,但它在创建数据库模型时抛出异常(在选择要包含在模型中的对象之后,包括一些存储过程)。

采取 2:

如上所述创建项目并安装 NuGet 包。

创建类库项目以促进 Oracle 交互。

在类库项目中安装了与上面相同的 NuGet 包。

向类库项目添加了 ADO.NET 实体数据模型,并向数据库模型添加了一些数据库对象。还向模型中添加了特定连接字符串的自定义构造函数,因为在 Azure Functions 中管理连接字符串是一组单独的令人头疼的问题,我将在稍后处理。

向类库项目添加了一个简单的包装方法,该方法从数据库模型调用存储过程:

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 Functions 项目中的类库的引用。

添加了调用 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);
    }

问题:在运行时,调用函数失败并出现此错误 消息:

Exception while executing function: GetNameByEmpNo -> The ADO.NET provider with invariant name 'Oracle.ManagedDataAccess.Client' is either not registered in the machine or application config file, or could not be loaded. See the inner exception for details. -> Unable to find the requested .Net Framework Data Provider. It may not be installed.

额外信息:通过控制台应用程序调用时,我的类库可以完美运行。此外,当调用不使用我的类库的函数时,我的 Azure Functions 应用程序可以完美运行...

我被难住了。有没有人有让这种技术组合协同工作的经验,并且可以提供一些关于我出错的地方的见解/提供使基本连接正常工作的步骤?

最佳答案

Azure Functions 中的 Entity Framework 默认提供程序为 System.Data.SqlClient,因此 SQL 连接无需任何配置更改即可工作,但这意味着您必须对 Oracle 连接执行一些特殊操作。问题似乎来自于 Oracle.ManagedDataAccess.Client 库假定在项目的 App.Config 或 Web.Config 文件中可用的配置值,每当您安装 Oracle.ManagedDataAcess.EntityFramework Nuget 包时都会插入这些值。 Azure Functions 没有配置文件,而且我无法找到任何方法在设置 json 文件中指定 Oracle 提供程序。

我在这个post中找到了解决方案

它建议绕过此机制并为 Oracle 创建 DbConfiguration,然后使用 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 Database First 生成 EDMX;这里的 MyEntities 是一个分部类,用于提供接受连接字符串的构造函数。

oracle 连接将使用指定的 DbConfiguration 类,并且任何 SQL 数据库连接将继续使用默认值。

我的解决方案是使用 Nuget 包:

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

关于visual-studio - Azure Functions、 Entity Framework 和 Oracle DB - 基本 POC 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50391453/

相关文章:

visual-studio - 符号问题 - 无法进入 .NET 代码

visual-studio - 为 COM 互操作注册 x64 程序集

c# - ASP.NET MVC 大型项目架构

c++ - 为什么 GetProcAddress 不起作用?

visual-studio - 在 Visual Studio 中撤消删除断点

c# - 无法将自定义值插入标识列 - Entity Framework

sql - EF 迁移正在删除列并尝试将不存在的列重命名回 Id

plsql - 更改 oracle 输出结果的方式

sql - 从 CTE 插入

oracle - 如何在Oracle 11g r2 Express版中更改字符集