Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 调试AzureFunction以及部署azure函数时缺少ProviderName_C#_Entity Framework_Azure_Azure Functions - Fatal编程技术网

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

C# 调试AzureFunction以及部署azure函数时缺少ProviderName,c#,entity-framework,azure,azure-functions,C#,Entity Framework,Azure,Azure Functions,我在获取DbContext以正确地从我的local.settings.json中提取连接字符串时遇到问题 背景: 这是一个Azure功能项目 主要问题代码位于System.Data.Entity.Internal.AppConfig 虽然我有一个local.settings.json文件,但这不是dotnet核心。是.NET4.6.1 错误消息: '应用程序配置文件中的连接字符串'shippoB_DevEntities'不包含所需的providerName属性。“” Json配置: {

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

背景:

  • 这是一个Azure功能项目
  • 主要问题代码位于
    System.Data.Entity.Internal.AppConfig
  • 虽然我有一个
    local.settings.json
    文件,但这不是dotnet核心。是.NET4.6.1
错误消息:

'应用程序配置文件中的连接字符串'shippoB_DevEntities'不包含所需的providerName属性。“”

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
    :这没有任何作用
  • shippob\u DevEntities
    的字符串值=设置为
    ConnectionString
    的值:这会引发新的错误,如下所示:

    不支持关键字元数据

  • 我尝试使用一个ADO连接字符串,该字符串抛出一个
    code-first
    异常,这似乎是在
    数据库优先
    方法中连接字符串不正确时发生的

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

到目前为止,我已经查阅了这两篇文章,其中一篇文章指出将提供者名称作为它自己的令牌;但是,这不起作用



有人知道在local.settings.json中用于实体框架连接的正确格式吗?

我以前遇到过类似的问题,我会使用以下方法来实现我的目的,您可以参考它:

local.settings.json

{
“IsEncrypted”:错误,
“价值观”:{

“AzureWebJobsStorage”:“DefaultEndpointsProtocol=https;AccountName=brucchstorage;AccountKey=for Azure函数。

因此解决方案最终变得微不足道。在
local.settings.json
中指定的
ProviderName
属性必须是大小写

来自最初的git hub讨论:

将提供程序名称显示为pascal大小写


以伪代码的大小写显示提供程序名称 很容易错过,但您的配置部分必须完全如下所示

"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"
  }
}  
以下几点很重要:

  • 确保连接字符串包含元数据信息
  • 如果从xml配置复制字符串,请确保取消勾选撇号
  • 确保
    ProviderName
    属性为camel case
  • 确保提供程序名称为
    System.Data.EntityClient
修复了部署中缺少providername的问题 注意,这个答案假设您正在尝试使用DbContext的无参数构造函数。如果您正在创建新代码,您可以很容易地遵循第二个向上投票的答案

我找到了一种绕过提供者名称问题的方法,同时仍然保留门户配置的使用,从而保留部署槽

private static string _connectionString = "name=ShipBob_DevEntities";

    static ShipBob_DevEntities()
    {
        if(!string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("AzureFunction")))
        {
            var connectionString = System.Environment.GetEnvironmentVariable("EntityFrameworkConnectionString");

            if (!string.IsNullOrEmpty(connectionString))
            {
                _connectionString = connectionString;
            }
        }
    }

    public ShipBob_DevEntities()
        : base(_connectionString)
    {
        this.Configuration.LazyLoadingEnabled = false;
    }  
这涉及开发人员在azure门户中创建应用程序设置作为标志。在我的情况下,它是AzureFunction。这确保我们的代码仅在azure函数中运行,并且此DbContext的所有其他客户端,无论是web应用程序、windows应用程序等,都可以继续按预期运行。这还涉及到添加正在将您到azure门户的连接字符串设置为应用设置,而不是实际的连接字符串。请使用完整的连接字符串,其中包含元数据信息,但不包含提供商名称

编辑 您需要编辑自动生成的.tt文件t4模板,以确保在首先使用db时不会覆盖此代码

以下是关于T4语法的链接:


这里有一个关于EF T4模板的解释:

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

  • 最重要的是我们理解local.settings.json文件 不适用于AZURE。它是以名称在本地运行您的应用程序 很明显。所以解决方案和这个文件无关

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

  • 为了使用,您需要在azure功能的
    应用程序设置下的azure门户上定义连接字符串
    连接字符串。在这里,您应该复制DBContext的连接字符串。如果是edmx,则如下所示
    
    using (var dbContext = new BruceDbContext(connString))
    {
        //TODO:
    }
    
    "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"
      }
    }  
    
    private static string _connectionString = "name=ShipBob_DevEntities";
    
        static ShipBob_DevEntities()
        {
            if(!string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("AzureFunction")))
            {
                var connectionString = System.Environment.GetEnvironmentVariable("EntityFrameworkConnectionString");
    
                if (!string.IsNullOrEmpty(connectionString))
                {
                    _connectionString = connectionString;
                }
            }
        }
    
        public ShipBob_DevEntities()
            : base(_connectionString)
        {
            this.Configuration.LazyLoadingEnabled = false;
        }  
    
    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());
                }
            }
        }
    
    var connString = ConfigurationManager.ConnectionStrings["myDBEntities"].ConnectionString;
    
    
     using (var dbContext = new myDBEntities(connString))
    {
            //TODO:
    }
    
    public partial class TestEntities: DbContext
    {
        public TestEntities(string connectionString)
            : base(connectionString)
        {
        }
    
    string connectionString = Environment.GetEnvironmentVariable("connectionStringAppSettings");
    
    using (var dbContext = new TestEntities(connectionString))
    {
    // Do Something
    }
    
    public partial class TestEntities : DbContext
        {
            public TestEntities ()
                : base("name=TestEntities")
            {
            }
    
    
    public partial class TestEntities
    {
        public TestEntities(string connectionString)
            : base(connectionString)
        {
        }
    }