从Azure函数V2连接到SQL Server时,Entity Framework 6出现问题

时间:2019-09-24 15:53:20

标签: entity-framework azure azure-functions

我正在尝试使用现有的库,该库是使用EF 6.0连接到数据库的.net库。由于Azure Functions没有app.config文件,因此我试图使用C#代码设置连接字符串。但是在使用数据库上下文连接到数据库时出现以下异常:

  

System.ArgumentException:具有不变名称'System.Data.SqlClient'的ADO.NET提供程序未在计算机或应用程序配置文件中注册,或者无法加载。有关详细信息,请参见内部异常。

     

System.ArgumentException:在已注册的.NET数据提供程序列表中找不到指定的不变名称'System.Data.SqlClient'

MyDBContext.partial.cs:

[DbConfigurationType(typeof(MyDbConfiguration))]
public partial class MyDBContext : DbContext
{
    public MyDBContext (string ConnectionString)
        : base(ConnectionString)
    {     
    }
}

public class MyDbConfiguration : DbConfiguration
{
    public MyDbConfiguration()
    {
        SetProviderServices("System.Data.SqlClient", SqlProviderServices.Instance);
        SetDefaultConnectionFactory(new SqlConnectionFactory());
    }
}

我有以下方法来获取DBContext。库方法将使用此方法来获取数据库上下文实例。

public MyDBContext GetDB( string metadata, string connectionString )
{
    EntityConnectionStringBuilder b = new EntityConnectionStringBuilder();
    b.Metadata = metadata;
    b.ProviderConnectionString = connectionString;
    b.Provider = "System.Data.SqlClient";
    return new MyDBContext (b.ConnectionString);
}

当我执行库方法以从Azure函数v2从数据库加载数据时,该函数内部调用上述方法以获取数据库上下文,然后连接到实际数据库。这里创建了MyDBContext对象,但是当它连接到db时,会发生以下异常。

  

System.ArgumentException:具有不变名称'System.Data.SqlClient'的ADO.NET提供程序未在计算机或应用程序配置文件中注册,或者无法加载。有关详细信息,请参见内部异常。

     

System.ArgumentException:在已注册的.NET数据提供程序列表中找不到指定的不变名称'System.Data.SqlClient'

1 个答案:

答案 0 :(得分:0)

我只是解决了此问题,但针对Azure函数V1。 在将EF与Azure函数一起使用时,可以在“ local.settings.json”文件中指定连接字符串,如下所示:

{
    "IsEncrypted": false,
    "Values": {
    "AzureWebJobsStorage": "",
    "AzureWebJobsDashboard": ""
    },
    "ConnectionStrings": {
        "YourEntities": {
            "ConnectionString":  "metadata=res://*/EF.yourModel.csdl|res://*/EF.yourModel.ssdl|res://*/EF.yourModel.msl;provider=System.Data.SqlClient;provider connection string='data source=yourServer;initial catalog=yourDB;persist security info=True;user id=yourUserID;password=yourPwd;MultipleActiveResultSets=True;App=EntityFramework'",
            "ProviderName": "System.Data.EntityClient"
        }
    }
}

请注意“ ProviderName”属性。大小写应如上所示,提供者应为“ EntityClient” 加上实际连接字符串的“提供程序连接字符串”属性应该用单引号引起来(我不确定为什么微软这样做,但这应该是这样)。

这将帮助您使用EF在本地运行功能应用程序,而无需进行任何其他更改

现在可以在Azure中进行部署。 local.settings.json不会部署到云中。顾名思义,它充当本地运行的配置文件。 因此,您需要在门户网站上的Azure函数应用程序的“配置”中设置连接字符串。 您可以在其中指定以下参数:

Name - 'YourEntities'
value - Just Connection string part from above json file
Type - 'Custom'
Slot Settings - according to your requirement

现在,如果您发现无法在此处指定ProviderName。如果您现在尝试运行功能,则将出现“缺少提供程序名称”的错误

在这里您可以使用扩展的DBConfiguration类。

按如下所示创建数据库配置类,并将提供程序指定为EntityType

public class YourDBContextConfig : DbConfiguration
{
    public YourDBContextConfig()
    {
    SetProviderServices("System.Data.EntityClient",
    SqlProviderServices.Instance);
    SetDefaultConnectionFactory(new SqlConnectionFactory());
    }

}

您可以在为DBContext创建部分类的同一文件中创建此类。

向您的Context类添加以下属性: [DbConfigurationType(typeof(YourDBContextConfig))]

还要确保您的部分上下文类具有构造函数,该构造函数将连接字符串作为参数并在初始化上下文时提供该字符串:

string connString = 
ConfigurationManager.ConnectionStrings["YourEntities"].ConnectionString;
using (YourEntities db = new YourEntities(connString))
{
}

这将适用于部署。