c# - 调试 AzureFunction 以及部署 azure 函数时缺少 ProviderName

标签 c# entity-framework azure azure-functions

我在获取 DbContext 来从 local.settings.json 正确提取连接字符串时遇到问题

上下文:

  • 这是一个 Azure 函数项目
  • 主要问题代码位于System.Data.Entity.Internal.AppConfig
  • 虽然我有一个 local.settings.json 文件,但这不是 dotnet core。这是.net 4.6.1

错误消息:

'The connection string 'ShipBob_DevEntities' in the application's configuration file does not contain the required providerName attribute."'

Json 配置:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "AzureWebJobsDashboard": ""
},

"ConnectionStrings": {
"ShipBob_DevEntities": {
  "ConnectionString": "metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string='data source=***;initial catalog=***;persist security info=True;User Id=***;Password=***;;multipleactiveresultsets=True;application name=EntityFramework'",
  "providerName": "System.Data.EntityClient"
    }
  }
}  

测试的配置版本:

  • 将提供程序名称移至实际的 ConnectionString token 值中:发生相同的错误
  • ConnectionString 属性内的 provider 属性设置为 EntityClient:这没有执行任何操作
  • ShipBob_DevEntities 的字符串值设置为 ConnectionString 的值:这会引发新的错误,例如

    keyword metadata is not supported

  • 我尝试使用 ADO 连接字符串,它会引发代码优先异常,当您的连接字符串在数据库优先方法中不正确时,似乎会发生这种情况。

我冒昧地使用dotPeek反编译了EntityFramework.dll,并将问题追溯到System.Data.Entity.Internal.LazyInternalConnection。 TryInitializeFromAppConfig。在此方法中,有一个对 LazyInternalConnection.FindConnectionInConfig 的调用,该调用会生成一个 ConnectionStringSettings 对象,该对象的 ProviderName 值设置为 null。不幸的是,我无法调试它似乎用来生成这个值的 AppConfig.cs 类,所以我陷入了困境。

enter image description here

到目前为止我已经查阅了这两篇文章。其中之一规定将提供商名称作为其自己的 token ;但是,这不起作用。

https://github.com/Azure/azure-functions-cli/issues/193
https://github.com/Azure/azure-functions-cli/issues/46

有人知道在 local.settings.json 中用于 Entity Framework 连接的正确格式吗?

最佳答案

我在这里经历了几个类似的问题和答案。他们中的许多人要么具有误导性,要么假设每个人都处于同一水平并了解 azure 功能的工作原理。对于像我这样的新手来说没有答案。我想在这里逐步总结我的解决方案。我不认为提供的答案是最好的选择,因为它迫使您更改自动生成的 edmx 文件,这些文件可能会被错误或下次更新数据库中的 edmx 覆盖。在我看来,这里最好的选择是使用连接字符串而不是应用程序设置。

  1. 最重要的是我们了解 local.settings.json 文件 不适用于 azure 。就是在本地运行你的应用程序,就像名字一样 明确地说。所以解决方案与此文件无关。

  2. App.Config 或 Web.Config 不适用于 Azure 函数连接字符串。如果您有数据库层库,则无法像在 Asp.Net 应用程序中那样使用其中任何一个来覆盖连接字符串。

  3. 为了使用,您需要在 Azure 函数的应用程序设置下的 Azure 门户上定义连接字符串。有 连接字符串。您应该在那里复制 DBContext 的连接字符串。如果是 edmx,则如下所示。有连接类型,我使用它 SQlAzure 但我使用自定义进行了测试(有人声称仅适用于自定义)两者都适用。

metadata=res:///Models.myDB.csdl|res:///Models.myDB.ssdl|res://*/Models.myDB.msl;provider=System.Data.SqlClient;provider connection string='data source=[yourdbURL];initial catalog=myDB;persist security info=True;user id=xxxx;password=xxx;MultipleActiveResultSets=True;App=EntityFramework

  • 设置完毕后,您需要读取应用程序中的 URL 并提供 DBContext。 DbContext 实现带有连接字符串参数的构造函数。默认情况下,构造函数没有任何参数,但您可以扩展它。如果您使用 POCO 类,您可以简单地修改 DbContext 类。如果您像我一样使用数据库生成的 Edmx 类,您不想接触自动生成的 edmx 类,而是想在同一命名空间中创建部分类并扩展此类,如下所示。
  • 这是自动生成的 DbContext

    namespace myApp.Data.Models
    {   
    
        public partial class myDBEntities : DbContext
        {
            public myDBEntities()
               : base("name=myDBEntities")
            {
            }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                throw new UnintentionalCodeFirstException();
            }
    
    }
    

    这是您创建的新分部类

    namespace myApp.Data.Models
    {
        [DbConfigurationType(typeof(myDBContextConfig))]
        partial class myDBEntities
        {
    
            public myDBEntities(string connectionString) : base(connectionString)
            {
            }
        }
    
          public  class myDBContextConfig : DbConfiguration
            {
                public myDBContextConfig()
                {
                    SetProviderServices("System.Data.EntityClient", 
                    SqlProviderServices.Instance);
                    SetDefaultConnectionFactory(new SqlConnectionFactory());
                }
            }
        }
    
  • 毕竟,您可以使用以下代码从 Azure 设置中的 Azure Function 项目中获取连接字符串,并将其提供给您的 DbContext myDBEntities 是您在 Azure 门户中为连接字符串指定的名称。
  • var connString = ConfigurationManager.ConnectionStrings["myDBEntities"].ConnectionString;
    
    
     using (var dbContext = new myDBEntities(connString))
    {
            //TODO:
    }
    

    关于c# - 调试 AzureFunction 以及部署 azure 函数时缺少 ProviderName,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46698103/

    相关文章:

    c# - Azure WebJob 在同一主机上调用 WebAPI

    mysql - 无法通过 MySQL Workbench 连接到 Azure MySQL

    c# - 将 "this"存储在结构方法的局部变量中有什么好处?

    c# - 如何在 C# 中为整个命名空间范围设置类型别名

    c# - 从谷歌发送电子邮件在生产服务器上失败但在本地主机上工作正常

    entity-framework - Entity Framework 是否有像 DataSet/DataTables 那样的缓存机制?

    c# - Entity Framework - 无法创建类型的常量值

    c# - 如何以编程方式关闭与数据库的所有现有连接

    c# - 为什么我的 Azure Function App 时间戳少了一个小时

    c# - Windows Azure 连接到 MySQL DB 中的 InvalidCastException