Deployed Azure Function gives a ProviderName error - c#

I have an Azure function application that when I debug it in my local PC, it won't give any error and will work correctly, but when I deploy it into the Azure Functions web, it will throw an error indicating that my Entities connection doesn't have the ProviderName specified.
I followed the solutions given by Missing ProviderName when debugging AzureFunction as well as deploying azure function, I have created a myDBContextConfig and added it to the Auto Generated dbContext file from my .edmx, but I still continue to have the same problem after deploying.
Here are some screenshots and config data I'm using:
the Error:
The local.settings.json:
{ "IsEncrypted": false,
"Values": {
//Some Values
},
"ConnectionStrings": {
"Entities": {
"ConnectionString": "metadata=res://*/Entities.csdl|res://*/Entities.ssdl|res://*/Entities.msl;provider=System.Data.SqlClient;provider connection string='data source=ES-HHASQL01\\SQLES;initial catalog=Entities;persist security info=True;Integrated Security=False;User ID=****;Password=****;MultipleActiveResultSets=True;application name=EntityFramework'",
"ProviderName": "System.Data.EntityClient"
}
}
}
And the Azure functions connection String:
The hidden connection follows the style of the quoted text below.
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
If any one can help me with this I would really appreciate it. Thank you.
Edit:
Well I have tested the issue with the code provided by #Joey Cai, and made the next changes:
the new App Settings connection string is has follows:
Data Source=tcp:*.database.windows.net,1433;Initial Catalog=***MultipleActiveResultSets=true;User ID=*;Password=***;Connection Timeout=30;App=EntityFramework;
I added the database configuration class to the Auto generated code from the dbContext has follows:
[DbConfigurationType(typeof(EntitiesConfig))]
public partial class Entities : DbContext
{
public Entities()
: base("name=Entities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
}
and created the class has especified by: #Joey Cai
namespace SameHasDbContext
{
public class EntitiesConfig : DbConfiguration
{
public EntitiesConfig()
{
SetProviderServices("System.Data.EntityClient", SqlProviderServices.Instance);
SetDefaultConnectionFactory(new SqlConnectionFactory());
}
}
}
But know I'm getting this error when running the azure function only if the connection type is SQLServer or SQLAzure, if it's set to Custom it still shows the ProviderNamer error shown before:

You can't add EF metadata about the connection in Azure Functions, as they do not use an app.config in which to specify it. This is not a part of the connection string, but is metadata about the connection besides the connection string that EF uses to map to a specific C# Class and SQL Provider etc. To avoid this, you could following the code as below.
[DbConfigurationType(typeof(DBContextConfig))]
partial class
{
public Entities(string connectionString)
: base(connectionString)
{
}
}
public class DBContextConfig : DbConfiguration
{
public DBContextConfig()
{
SetProviderServices("System.Data.EntityClient", SqlProviderServices.Instance);
SetDefaultConnectionFactory(new SqlConnectionFactory());
}
}

Related

Entity Framework in Azure Function in Visual Studio

In Visual Studio I have an Azure Function, written in C#, which is supposed to read from an Azure SQL database using Entity Framework (EF6).
I cannot get Entity Framework to work. When I publish the Azure Function I get the error:
The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development. This will not work correctly. To fix this problem do not remove the line of code that throws this exception. If you wish to use Database First or Model First, then make sure that the Entity Framework connection string is included in the app.config or web.config of the start-up project. If you are creating your own DbConnection, then make sure that it is an EntityConnection and not some other type of DbConnection, and that you pass it to one of the base DbContext constructors that take a DbConnection. To learn more about Code First, Database First, and Model First see the Entity Framework documentation here: http://go.microsoft.com/fwlink/?LinkId=394715
None of this worked.
I also tried to add a project.json file in Azure as recommended by many websites but that didn’t change anything.
Here is the C#.
public static class Function1
{
[FunctionName("Function1")]
public static void Run([TimerTrigger("*/100 * * * * *")]TimerInfo myTimer, TraceWriter log)
{
try {
using (var qc = new quotecandyEntities()) {
if (qc.Users.Any()) {
log.Info($"The last user is {qc.Users.Last().Email}.");
} else {
log.Info("No users found in database.");
}
}
} catch (Exception ex) {
log.Error($"Error: {ex.Message}");
}
}
}
According to your description, I assumed that you are using Database First or Model First, and you configured the wrong Entity Framework connection string for your Entity Data Model. I tested and found that if my directly copy the connection string from Azure Portal while I am using Database First, I would encounter the similar issue you provided as follows:
For Database First, I would recommend you modify the generated Model.Content.cs and configure your DbContext as follows:
public partial class Entities : DbContext
{
public Entities():base(ConfigurationManager.ConnectionStrings["Entities"].ConnectionString)
{
}
}
Note: You could modify the t4 template and make sure you modification for your DbContext does not overridden after you updated the model from your database.
For dev, you could set your connection string under local.settings.json file as follows:
"ConnectionStrings": {
"Entities": "metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string='data source={server-name}.database.windows.net;initial catalog={db-name};persist security info=True;user id={username};password={password};MultipleActiveResultSets=True;App=EntityFramework'"
}
Before publishing to azure, you could create a connection string with the same as you configured under local.settings.json file and set the connection string as follows:
Moreover, you could follow this similar issue about the approach for using EF Database First in Azure Function.
since i had hard time setting this even with post here is the complete version
project1 (azure function) :
local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"AzureWebJobsDashboard": "UseDevelopmentStorage=true",
"schedule": "*/1 * * * * *"
},
"ConnectionStrings": {
"dbEntities": "metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string='data source=someAzureServer.database.windows.net;initial catalog=someDB;persist security info=True;user id=foo;password=XXXX;MultipleActiveResultSets=True;App=EntityFramework'",
"ProviderName": "System.Data.EntityClient"
}
}
Project2(dll):
Model1.Context.cs
namespace main2
{
using System;
using System.Configuration;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class dbEntities : DbContext
{
public crypto_dbEntities()
: base(ConfigurationManager.ConnectionStrings["dbEntities"].ConnectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
}
now rename :
-connectionstring name
-server name
-db name
-user name
-password
so i remember later too;)

Entity Framework - can't find/connect to localdb from within my project?

I'm following this guide:
https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application
My project is named WebApplication1. I have installed Entity Framework via nuget.
I have a class called LoyaltyUsersContext.cs:
namespace WebApplication1.DAL
{
public class LoyaltyUsersContext : DbContext
{
public LoyaltyUsersContext() : base("LoyaltyUsersContext")
{
}
public DbSet<LoyaltyUser> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
I have added the following value to my in web.config:
<add name="LoyaltyUsersContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=Webapplication1;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
However, when I go to Server Explorer > Add Connection (MiscroSoft SQL Server, localdb doesn't show up under Server name - there aren't anything. There's also a "LoyaltyUsersContext(WebApplication1) under Data Connections, but I get an error when I try to refresh it.
Any idea why I can't seem to connect to localdb? I'm hoping it's just a connection string error or something.

Code First always wants to create new database when deploying to another PC

i have a win-form app that uses CodeFirst to work with data.
after creating database from my models i have imported records to it from another database.it works fine in my PC but when i deploy my app to another pc, codefirst tries to create new database and throws this error :
System.Data.Entity.Core.EntityException: The underlying provider failed on Open. --->
System.Data.SqlClient.SqlException: Cannot create file
'E:\New folder (2)\Release\MyDB_log.ldf' because it already exists.
Change the file path or the file name, and retry the operation.
Could not open new database 'MyDB'. CREATE DATABASE is aborted.
Cannot attach the file 'E:\New folder (2)\Release\MyDB.mdf' as database 'MyDB'.
connection string :
<connectionStrings>
<add name="AppDbContext"
connectionString="Server=.\sqlexpress;AttachDbFilename=|DataDirectory|\MyDB.mdf;Database=MyDB;Trusted_Connection=Yes;" providerName="System.Data.SqlClient" />
</connectionStrings>
AppDbContext :
public class AppDbContext :DbContext
{
static AppDbContext() {
Database.SetInitializer<AppDbContext>(null);
}
public DbSet<Stock> Stocks { get; set; }
public DbSet<Report> Reports { get; set; }
}
Migration class:
internal sealed class Configuration : DbMigrationsConfiguration<Sita_Election.DAL.AppDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
ContextKey = "Sita_Election.DAL.AppDbContext";
AutomaticMigrationDataLossAllowed = false;
}
protected override void Seed(Sita_Election.DAL.AppDbContext context)
{
}
}
so i want to use existing database that is created in development with codefirst,how can i do this ?
Is there any reason to have a database per application?
I would suggest using just a SQL DB if possible.
Thanks,
Phill
Your connection string is using a trusted connection so your IIS user is going to need access to that file or you could switch to a sql login. http://th2tran.blogspot.com/2009/06/underlying-provider-failed-on-open.html

System.data.SQLite entity framework code first programmatic providername specification

I've spent a while on this now and have only found a workaround solution that I'd rather not do...
I have a context as shown below. Is there a programmatic way to specify the database to connect to via the constructor, and get it to use the System.Data.SQLite entity framework provider to connect to a SQLite database? This is working via the app.config (with a connectionstring called "Context"), but not via any programmatic way I can find of supplying it. I have tried using an entity connectionstring builder and that produces the following string:
provider=System.Data.SQLite;provider connection string='data
source="datafile.db"'
When the context is first queried with this string I get a message "Keyword not supported: 'provider'."
public class Context : DbContext
{
public IDbSet<Test> Tests { get; set; }
public Context()
: base("Context")
{
}
}
*Edit.
I may have solved this by implementing my own connectionfactory:
public class ConnectionFactory : IDbConnectionFactory
{
public DbConnection CreateConnection(string nameOrConnectionString)
{
return new SQLiteConnection(nameOrConnectionString);
}
}
Then setting:
Database.DefaultConnectionFactory = new ConnectionFactory();
However, it seems like there should be a built in way to do this, and also one that does not involve overriding the global default connection factory.

Entity Framework - using the same DbContext with different connection strings

I'm currently trying to use the same DbContext (I have two databases, of identical structure) in my application. I'm not quite sure what I'm doing wrong, but here's my current code - hopefully it should be pretty obvious what I'm trying to do. I'm using EF Database First (which the error at the bottom seems not to suggest).
My context factory code:
public class HOLContextFactory
{
public static HOLDbEntities Create()
{
return new HOLDbEntities(); // Works
}
public static HOLDbQuoteEntities CreateQuote()
{
return new HOLDbQuoteEntities(); // Gives error
}
}
public partial class HOLDbQuoteEntities : HOLDbEntities
{
public HOLDbQuoteEntities()
: base("HOLDbQuoteEntities") // This should send "HOLDbQuoteEntities" as the base connection string?!
// Also tried "name=HOLDbQuoteEntities"
{
}
}
Web.config connection strings:
<add name="HOLDbEntities" connectionString="metadata=res://*/HOLDbContext.csdl|res://*/HOLDbContext.ssdl|res://*/HOLDbContext.msl;provider=System.Data.SqlClient;provider connection string=<connstringdetails>" providerName="System.Data.EntityClient" />
<add name="HOLDbQuoteEntities" connectionString="metadata=res://*/HOLDbContext.csdl|res://*/HOLDbContext.ssdl|res://*/HOLDbContext.msl;provider=System.Data.SqlClient;provider connection string=<connstringdetails>" providerName="System.Data.EntityClient" /> // using diff database - same structure
Error I'm getting when using "HOLDbQuoteEntities" :
Code generated using the T4 templates for Database First and Model
First development may not work correctly if used in Code First mode.
To continue using Database First or Model First ensure that the Entity
Framework connection string is specified in the config file of
executing application. To use these classes, that were generated from
Database First or Model First, with Code First add any additional
configuration using attributes or the DbModelBuilder API and then
remove the code that throws this exception**
Entity Framework needs to use the actual entities object:
public class HOLContextFactory
{
public static HOLDbEntities Create()
{
// default connection string
return new HOLDbEntities();
}
public static HOLDbEntities CreateQuote()
{
// specified connection string
return new HOLDbEntities ("HOLDbQuoteEntities");
}
}
public partial class HOLDbEntities
{
public HOLDbEntities(string connectionString)
: base(connectionString)
{
}
}
}
I've done the same thing in one of my project. I am creating my entity context using metadata=res://*/
Try this:
<add name="HOLDbEntities" connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string=<connstringdetails>" providerName="System.Data.EntityClient" />
<add name="HOLDbQuoteEntities" connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string=<connstringdetails>" providerName="System.Data.EntityClient" />

Categories