我在uiid
从DbContext
上下文:
local.settings.json
System.Data.Entity.Internal.AppConfig
文件,但这不是dotnet核心。这是.net 4.6.1 错误讯息:
'应用程序配置文件中的连接字符串'ShipBob_DevEntities'不包含必需的providerName属性。“''
Json配置:
local.settings.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"
}
}
}
标记值:相同的错误ocurrs ConnectionString
属性中的provider
属性设置为ConnectionString
:这没有做任何事情将EntityClient
字符串值= ShipBob_DevEntities
的值:这会引发新的错误
不支持关键字元数据
我尝试使用ADO连接字符串,该字符串会引发ConnectionString
异常,这种异常似乎是在code first
方法中连接字符串不正确时发生的。
我冒昧地使用 dotPeek 反编译database first
并将问题追溯到EntityFramework.dll
。在此方法中,有一个System.Data.Entity.Internal.LazyInternalConnection.TryInitializeFromAppConfig
调用,它会将LazyInternalConnection.FindConnectionInConfig
对象的ConnectionStringSettings
值设置为null。不幸的是我无法调试它似乎用于生成此值的ProviderName
类,所以我被卡住了。
到目前为止,我已经查阅了这两篇文章。其中一个说明将提供者名称作为自己的令牌;但是,这不起作用。
https://github.com/Azure/azure-functions-cli/issues/193
https://github.com/Azure/azure-functions-cli/issues/46
有没有人知道在local.settings.json中使用正确的格式来进行实体框架连接?
答案 0 :(得分:11)
所以解决方案最终变得微不足道。 ProviderName
必须中指定的local.settings.json
属性为驼峰式。
从原来的git hub讨论:
https://github.com/Azure/azure-functions-cli/issues/46
将提供者名称显示为pascal case
https://github.com/Azure/azure-functions-cli/issues/193
以伪代码显示提供程序名称为驼峰式大小写
这很容易错过,但您的配置部分必须完全如下
"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"
}
}
这些要点很重要:
ProviderName
属性为驼峰 System.Data.EntityClient
注意,这个答案假设您正在尝试使用DbContext的无参数构造函数。如果您要创建新代码,可以轻松地按照第二个提出的答案
我找到了一种绕过提供程序名称问题的方法,同时仍保留使用门户网站配置和部署插槽的方法。它涉及使用静态属性
设置db context的默认连接字符串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;
}
这涉及开发人员在天蓝色门户中创建应用程序设置作为标志。就我而言,它是 AzureFunction 。这确保我们的代码仅在azure函数中运行,并且此DbContext的所有其他客户端,无论是Web应用程序,Windows应用程序等,仍然可以继续按预期运行。这还涉及将连接字符串作为 AppSetting 添加到azure门户,而不是实际的连接字符串。请使用完整的连接字符串,包括元数据信息,但不包含提供商名称!
如果您首先使用db,则需要编辑自动生成的.tt文件t4模板,以确保不会覆盖此代码。
以下是T4语法的链接:https://docs.microsoft.com/en-us/visualstudio/modeling/writing-a-t4-text-template
以下是对EF T4模板的解释:https://msdn.microsoft.com/en-us/library/jj613116(v=vs.113).aspx#1159a805-1bcf-4700-9e99-86d182f143fe
答案 1 :(得分:9)
我在这里经历了几个类似的问题和答案。他们中的许多人要么误导,要么假设每个人都处于同一水平,并且了解天蓝色功能是如何运作的。像我这样的新手没有答案。我想在此总结一下我的解决方案。我不认为提供答案是最佳选择,因为它会强制您更改自动生成的edmx文件,这些文件可能被错误覆盖或从数据库下次更新edmx。此外,最好的选择是在我看来使用连接字符串而不是应用程序设置。
最重要的是我们了解local.settings.json文件 不是为了AZURE。它是在本地运行您的应用程序名称 清楚地说。所以解决方案与此文件无关。
App.Config或Web.Config不适用于Azure功能连接字符串。如果您有数据库层库,则无法像使用Asp.Net应用程序那样使用其中任何一个覆盖连接字符串。
为了使用,您需要在Azure功能的Application Settings
下的Azure文档中定义连接字符串。有
连接字符串。你应该复制你的DBContext的连接字符串。如果它是edmx,它将如下所示。有连接类型,我使用它SQlAzure但我用Custom测试(有人声称只适用于自定义)适用于两者。
元数据= RES:// /Models.myDB.csdl|res:// /Models.myDB.ssdl|res://*/Models.myDB.msl;provider=System。 Data.SqlClient提供方 连接字符串='数据源= [yourdbURL];初始 catalog = myDB; persist security info = True;用户 ID = XXXX;密码= XXX; MultipleActiveResultSets = TRUE;应用=的EntityFramework
这是自动生成的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());
}
}
}
var connString = ConfigurationManager.ConnectionStrings["myDBEntities"].ConnectionString; using (var dbContext = new myDBEntities(connString)) { //TODO: }
答案 2 :(得分:0)
之前我遇到过类似的问题,我会用以下方法来实现我的目的,你可以参考它:
<强> local.settings.json 强>
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=brucchstorage;AccountKey=<AccountKey>",
"AzureWebJobsDashboard": "DefaultEndpointsProtocol=https;AccountName=brucchstorage;AccountKey=<AccountKey>",
"sqldb-connectionstring": "Data Source=.\\sqlexpress;Initial Catalog=DefaultConnection;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
},
"ConnectionStrings": {
"Bruce_SQLConnectionString": "Data Source=.\\sqlexpress;Initial Catalog=DefaultConnection;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
}
}
用于检索连接字符串:
var connString = ConfigurationManager.AppSettings["sqldb-connectionstring"];
//or var connString = ConfigurationManager.ConnectionStrings["Bruce_SQLConnectionString"].ConnectionString;
using (var dbContext = new BruceDbContext(connString))
{
//TODO:
}
或者您可以为DbContext
初始化无参数构造函数,如下所示:
public class BruceDbContext:DbContext
{
public BruceDbContext()
: base("Bruce_SQLConnectionString")
{
}
public BruceDbContext(string connectionString) : base(connectionString)
{
}
}
然后,您可以为DbContext
创建实例,如下所示:
using (var dbContext = new BruceDbContext(connString))
{
//TODO:
}
此外,您可以参考Local settings file获取Azure功能。
答案 3 :(得分:0)
以下两种对我有用的方法:
方法1
metadata = res:// /xxx.csdl|res:// /xxx.ssdl|res://*/xxx.msl;provider=System.Data.SqlClient;提供商连接字符串='数据源= xxx.database.windows.net;初始目录= xxx;用户ID = xxx;密码= xxx; MultipleActiveResultSets = True; App = EntityFramework'
public partial class TestEntities: DbContext
{
public TestEntities(string connectionString)
: base(connectionString)
{
}
string connectionString = Environment.GetEnvironmentVariable("connectionStringAppSettings");
using (var dbContext = new TestEntities(connectionString))
{
// Do Something
}
方法2
此处的目标是使类“ TestEntities”保持原样,以避免方法1出现此问题
将连接字符串添加到“方法1”中的“应用程序设置”(分别为local.settings.json)中
按原样保留TestEntities
public partial class TestEntities : DbContext
{
public TestEntities ()
: base("name=TestEntities")
{
}
public partial class TestEntities
{
public TestEntities(string connectionString)
: base(connectionString)
{
}
}