Adr*_*ian 12 c# entity-framework azure azure-functions
我有一个问题是DbContext从我的正确拉出我的连接字符串local.settings.json
语境:
System.Data.Entity.Internal.AppConfiglocal.settings.json文件,但这不是dotnet核心.这是.net 4.6.1错误信息:
'应用程序配置文件中的连接字符串'ShipBob_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"
}
}
}
Run Code Online (Sandbox Code Playgroud)
配置版本测试:
ConnectionString标记值:相同的错误ocurrsprovider属性内的ConnectionString属性设置为EntityClient:这没有做任何事情使ShipBob_DevEntities字符串值=为值ConnectionString:这会引发新的错误
不支持关键字元数据
我尝试使用ADO连接字符串,该字符串抛出code first异常,当您的连接字符串在database first方法中不正确时,似乎会发生异常.
我已经冒昧地EntityFramework.dll使用dotPeek进行反编译,并将问题追溯到System.Data.Entity.Internal.LazyInternalConnection.TryInitializeFromAppConfig.在这个方法中,有一个调用LazyInternalConnection.FindConnectionInConfig吐出一个ConnectionStringSettings对象,该对象的ProviderName值设置为null.不幸的是我无法调试AppConfig.cs它似乎用来生成这个值的类,所以我被卡住了.
到目前为止,我已经查阅了这两篇文章.其中一个说明将提供者名称作为自己的令牌; 但是,这不起作用.
https://github.com/Azure/azure-functions-cli/issues/193
https://github.com/Azure/azure-functions-cli/issues/46
有没有人知道在local.settings.json中使用正确的格式进行实体框架连接?
Adr*_*ian 11
所以解决方案最终变得微不足道.必须是camel case中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
在伪代码中显示提供者名称是camel case
这很容易错过,但您的配置部分必须完全如下
"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"
}
}
Run Code Online (Sandbox Code Playgroud)
这些要点很重要:
ProviderName属性是驼峰式的System.Data.EntityClient 注意,这个答案假设您正在尝试使用DbContext的无参数构造函数.如果您要创建新代码,您可以轻松地按照第二个upvoted答案
我找到了一种绕过提供程序名称问题的方法,同时仍保留使用门户网站配置和部署插槽的方法.它涉及使用静态属性设置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;
}
Run Code Online (Sandbox Code Playgroud)
这涉及开发人员在azure门户中创建应用程序设置作为标志.在我的例子中,它是AzureFunction.这确保我们的代码仅在azure函数中运行,并且此DbContext的所有其他客户端,无论是Web应用程序,Windows应用程序等,仍然可以继续按预期运行.这还涉及将连接字符串作为AppSetting添加到azure门户,而不是实际的连接字符串.请使用完整的连接字符串,包括元数据信息但没有提供者名称!
您需要编辑自动生成的.tt文件t4模板,以确保在首先使用db时不会覆盖此代码.
以下是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 = vs133).aspx#1159a805-1bcf- 4700-9e99-86d182f143fe
我在这里经历了几个类似的问题和答案.他们中的许多人要么误导,要么假设每个人都处于同一水平,并且了解天蓝色功能是如何运作的.像我这样的新手没有答案.我想在此总结一下我的解决方案.我不认为提供答案是最佳选择,因为它会强制您更改自动生成的edmx文件,这些文件可能被错误覆盖或从数据库下次更新edmx.此外,最好的选择是在我看来使用连接字符串而不是应用程序设置.
最重要的是我们了解local.settings.json文件不是为了AZURE.这是在名称显然是在本地运行您的应用程序.所以解决方案与此文件无关.
App.Config或Web.Config不适用于Azure功能连接字符串.如果您有数据库层库,则无法像使用Asp.Net应用程序那样使用其中任何一个覆盖连接字符串.
为了使用,您需要Application Settings在Azure功能下的azure门户上定义连接字符串.有连接字符串.你应该复制你的DBContext的连接字符串.如果它是edmx,它将如下所示.有连接类型,我使用它SQlAzure但我用Custom测试(有人声称只适用于自定义)适用于两者.
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
这是自动生成的DbContext
namespace myApp.Data.Models
{
public partial class myDBEntities : DbContext
{
public myDBEntities()
: base("name=myDBEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
}
Run Code Online (Sandbox Code Playgroud)
这是你创建的新的部分类
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());
}
}
}
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)var connString = ConfigurationManager.ConnectionStrings["myDBEntities"].ConnectionString; using (var dbContext = new myDBEntities(connString)) { //TODO: }
| 归档时间: |
|
| 查看次数: |
3798 次 |
| 最近记录: |