Connection string for Entity Framework in an Azure Function - entity-framework

I'm creating an Azure Function and I've added a reference to a project that uses Entity Framework. I've copied the connection string from that project and pasted in the local.settings.json file inside the ConnectionStrings object as a valid EF connection string.
metadata=res://*/xxx.csdl|res://*/xxx.ssdl|res://*/xxx.msl;
provider=System.Data.SqlClient;
provider connection string=&quote;
data source=xxx;
initial catalog=xxx;
user id=xxx;
password=xxx;
MultipleActiveResultSets=True;
App=EntityFramework
&quote;
But it's given me this exception:
Keyword not supported: metadata.
If I use a valid SQL connection string (like below),
data source=xxx;
initial catalog=xxx;
user id=xxx;
password=xxx;
MultipleActiveResultSets=True;
App=EntityFramework
I've this exception:
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
How could I create a connection to my database in an Azure function using Entity Framework? I'm using .NET framework and for EF I'm using database first.
I'm init my database context as follow:
using (XxxDB db = new XxxDB())
{ }
Meanwhile, I've created an overload for the contrustor XxxDB
public XxxDB(string connectionString): base(new EntityConnection(connectionString), true)
{ }
And pass the SQL connection string when creating the XxxDB and got this error:
Keyword not supported: data source.

Ok, this is caused by how EF model first connection strings are generated. The EF connection string builder requires a plain connection string in the constructor. Then you add the metadata section for model first.
When you create new connection string to pass to a DB context string builder, change this:
public XxxDB(string connectionString): base(new EntityConnection(connectionString), true)
{ }
to
public XxxDB(string connectionString): base(GetEntityConnection(connectionString), true)
{ }
private static string GetEntityConnection(string connectionString)
{
var efConnection = new EntityConnectionStringBuilder();
efConnection.ProviderConnectionString = connectionString;
// res://*/xxx.csdl|res://*/xxx.ssdl|res://*/xxx.msl
var model = "xxx";
// this is what's missing in your question
efConnection.Metadata = string.Format("res://*/Model.{0}.csdl|res://*/Model.{0}.ssdl|res://*/Model.{0}.msl", model);
return efConnection.ConnectionString;
}

Related

The model backing the 'DataContext' context has changed since the database was created

I am trying to use Code First with Migrations. Even though there are no current changes to my model, I'm getting an exception. When I add a migration, the up and down are empty, but I get a runtime error with the message as follows:
An exception of type 'System.InvalidOperationException' occurred in
EntityFramework.dll but was not handled in user code
Additional information: The model backing the 'MyDataContext' context
has changed since the database was created. Consider using Code First
Migrations to update the database (http://go.microsoft.com/fwlink/?
My architecture is as follows:
DataAccess project that includes the context, fluid configurations and migrations code
Model project that contains the poco classes
Web API and MVC projects that each contain the connections string in their respective web.config files.
Additionally I have the following code:
DbInitializer
public static MyDataContext Create()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDataAccess.MyDataContext, MyDataAccess.Migrations.Configuration>());
return new MyDataContext(ConfigurationManager.ConnectionStrings["MyDataContext"].ConnectionString, null);
}
I started with AutomaticMigrationsEnabled = false; in the migration Configuration constructor, as it was my understanding that this would allow (and require) me to have more control over when migrations were applied. I have also tried setting this to true but with the same result.
I added a new migration upon receiving this error, and the Up method was empty. I updated the database to this new migration, and a record was created in the _migrationHistory table, but I still receive the error when I attempt to run the application. Also, the seed data was not added to the database.
protected override void Seed(MyDataAccess.MyDataContext context)
{
IdentityResult ir;
var appDbContext = new ApplicationDbContext();
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(appDbContext));
ir = roleManager.Create(new IdentityRole("Admin"));
ir = roleManager.Create(new IdentityRole("Active"));
ir = roleManager.Create(new IdentityRole("InActive"));
var userNamager = new UserManager<User>(new UserStore<User>(appDbContext));
// assign default admin
var admin = new User { UserName = "administrator", Email = "myAdmin#gmail.com" };
ir = userNamager.Create(admin, "myp#55word");
ir = userNamager.AddToRole(admin.Id, "Admin");
}
where
public class ApplicationDbContext : IdentityDbContext<User>
{
public ApplicationDbContext()
: base("MyDataContext", throwIfV1Schema: false)
{
}
...
The question: If Add-Migration isn't seeing any change in the model, why do I get this error when I run? Why isn't the seed code being hit? How do I fix this, or if that can't be determined, how do I further determine the root cause?
I am not sure if you found the answer to your problem, but this other answer I found here actually did it for me:
Entity Framework model change error
I actually ended up deleting the __MigrationHistory table in SQL Server which I didn't know it was being created automatically.
The article also talks about the option to not generate it I think by using this instruction: Database.SetInitializer<MyDbContext>(null); but I have not used it, so I am not sure if it works like that
This worked for me.
Go to Package Manager Console and Run - Update-Database -force
I bet your data context is not hooking up the connection string.
Check if it's not initialized with a localdb (something like (localdb)\v11.0) and not working with that when you might think it's set to something else.
My issue ended up being a conflict between Automatic Migrations being enabled and the initializer MigrateDatabaseToLatestVersion as described here.

MVC 4 project using a class library EF model

Using an EF model in the Models folder in my MVC 4 project, I succeeded to display data in a razor view using a coded class named Prod and a controller method as next:
public ActionResult Index()
{
IEnumerable<Prod> Pr = from p in db.Products
select new Prod
{
ProductId = p.ProductID,
ProductName = p.ProductName
};
return View(Pr);
}
Now I am trying to do the same thing using a model in a class library instead of the current one, so I added to my solution a new class library, added then a model using the same connection string, and mapping the same entities, then added to my MVC project a reference to the new class library, and put at the top of both MyController and Prod class the next:
using MyClassLibrary;
Then I deleted the old model, now when I try to display the view, I get the following error:
Unable to load the specified metadata resource.
Any help please ?
When you move or rename the project the data context (.edmx) is in the metadata part of the Entity Framework connection string has to change
you can try have
connectionString="metadata=res://*/MyModel.csdl|res://*/MyModel.s‌​sdl|res://*/MyModel.msl;
instead of
connectionString="metadata=res://*/Models.MyModel.csdl|res://*/Models.MyModel.s‌​sdl|res://*/Models.MyModel.msl;
or try deleting your context and recreating it then check the connection string it adds automatically.
You need to put your connectionstring in web.config in Mc4 web project
You need to Mention the datasource in the connection string.
If you have not used any other web.config file for views. Use you generic web.config file and upload a connection string with New datasource name , user and password.

Entity framework connection string reference from another project

I have a solution consisting of 4 projects. MVC, WCF, Business LYR, DataAcess. I am using entity framework for database transaction. My requirement is that i want to fetch the entity connectionstring only from MVC webconfig without refering in APP.cofig of acess layer. Is it possible in this scenario?
While I tried the following code I got an error.
this.ConnectionString="data source=cmh-sosql;initial catalog=Student;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework";
System.Data.SqlClient.SqlConnectionStringBuilder scsb = new System.Data.SqlClient.SqlConnectionStringBuilder(this.ConnectionString);
EntityConnectionStringBuilder ecb = new EntityConnectionStringBuilder();
ecb.Metadata = "res://*/schoolModel.csdl|res://*/schoolModel.ssdl|res://*/schoolModel.msl";
ecb.Provider = "System.Data.SqlClient";
ecb.ProviderConnectionString = scsb.ConnectionString;
using (SchoolDB schoolDB = new SchoolDB(ecb.ConnectionString))
Error: The entity type student is not part of the model for the current context.
You are absolutely correct. I got the solution. There is no need to keep any string in webconfig for reference to a entity model. We can use the above code for reference it. But the change is to configure the context object.
public SchoolDB(string connectionString)
: base(connectionString)
{
}
We need to change the constructor also by this format.
thanks Sampath

DBcontext, dynamically specify connection string

I'm dealing with a C# application using EntityFramework and an object derived from DbContext.
I need to set programmatically the connection string when a new instance of MyDbContext object is created. In order to do so I use the following code:
public MyDbContext(string myString)
{
this.Database.Connection.ConnectionString = myString
}
myString = "Server=MYSERVER\\SQLEXPRESS; Database=MyDB; User ID=user; Password=pass;";
or
myString = "Data Source=|DataDirectory|\\AirecCalcDatabase.sdf";
The database providers are different for the two strings. SQLExpress for the first one, SQLCompact for the second one.
If I try to run this code with the first string, I get ArgumentException coming from the connection string. For example "Keyword not valid: server" but also "Keyword not valid: database". The connection string works when using the DbContext with no arguments, which is, reading the string from app.config
When you're wanting to use CE, you may need to change the DefaultConnectionFactory to point to SQL CE:
Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
See this blog post for more information

Is there a way to change connection string in database first?

I have several databases, the schema of them are same. When I use database-first, the connection string is specified when I create the edmx file. I want to know, is there a way to change the connection string? This is, so I can choose which database to operate.
We do not store connection strings in our web.configs, so the accepted solution would not work for us. If you simply attempt to provide the connection string via the base DbContext constructor, you'll get the following exception:
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.
To resolve this, create a partial class of your context as follows and format your connection string with the additional EF metadata (where MyContext is your context model name (e.g. your model name is MyModel.edmx, than the MyContext in code below is replaced with MyModel with all three extensions .csdl, .ssdl, .msl used)):
public partial class MyContext
{
public MyContext(string connStr)
: base(string.Format(#"metadata=res://*/MyContext.csdl|res://*/MyContext.ssdl|res://*/MyContext.msl;provider=System.Data.SqlClient;provider connection string='{0}'", connStr))
{
}
}
Change the connection string in the web.config file.
<connectionStrings>
<add name="SandBoxEntities" connectionString="metadata=r... />
</connectionStrings>
I abbreviated the actual connection string because it isn't important -- just wanted to give you an idea of what to look for in the web.config file.
You can also change your connection strings programatically. Check out Example 16.2. Programmatically modifying an EntityConnectionString.
You can define multiple connection string in web.config and then use them in your code perhaps your job.
for example:`
<connectionStrings>
<add name="conStr1" connectionString="metadata=r... />
</connectionStrings>`
<connectionStrings>
<add name="conStr2" connectionString="metadata=r... />
</connectionStrings>`
and so on
and your context class constructor get connection string name as parameter:
public MyContext(string connStr)
: base(connStr) { }
Ok. now you can use in your code as below:
using (var db = new MyContext("name=conStr1"))
{
//your code here
}
and then
using (var db = new MyContext("name=conStr2"))
{
//your code here
}