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
}
Related
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="e;
data source=xxx;
initial catalog=xxx;
user id=xxx;
password=xxx;
MultipleActiveResultSets=True;
App=EntityFramework
"e;
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;
}
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
I want to use Entity Framework without app.config file.
I want to define a string variable Connection String in my code and use that to connect to the database.
Please show me the way if it is possible.
You're not mentioning what approach you're using (database-first, model-first, code-first) - but basically, in the end, you need to define a string variable and assign it a valid EF connection string
string myConnectionString = "...(define a valid EF connection string here)......";
Example for database-first approach:
string myConnectionString = #"metadata=.\Model1.csdl|.\Model1.ssdl|.\Model1.msl;provider=System.Data.SqlClient;provider connection string="";data source=.;initial catalog=test;integrated security=True;multipleactiveresultsets=True;App=EntityFramework""";
and then use that to create your ObjectContext (database- and model-first) or DbContext (code-first)
using(ObjectContext ctx = new ObjectContext(myConnectionString))
{
// do your EF magic here.....
}
But quite honestly - I think this is a really bad idea since this makes it impossible for you to move your application to another machine - no one else can install and run this, since the connection string is hard-coded into your C# code..... the whole point of having config files is so that you can change / adapt things like connection strings so that they are not tied to a single machine/location but can be adapted to the particular needs of a given user / customer....
I am using EF 4.1, and I create a normal EF edmx file.
I generate it from a DB.
When it's been generated I rightclick and select add code generation item, to generate new classes, and use the DbContext instead. I use the template DbContext generator.
Everything works fine.
Then I trie to query the context:
using (var context = new PasDBEntities())
{
var client=context.ClientCompanies.SingleOrDefault(_=>_.ID==clientCompanyId);
if(client!=null)
I have no problem creating a new instance of the context but when I try to query it the problem occur. I get stuck on the UnintentionalCodeFirstException.
And gets the error:
{"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."}
I don't want to use code first, but I don't know if I can "switch" it off, or where the problem is.
For reference, here is my constructor ...
public partial class PasDBEntities : DbContext
{
public PasDBEntities()
: base("PasDBEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
...and connection string:
<connectionStrings>
<add name="PasDBEntities"
connectionString="metadata=res://*/PasDB.csdl|
res://*/PasDB.ssdl|
res://*/PasDB.msl;
provider=System.Data.SqlClient;
provider connection string="
data source=localhost;
initial catalog=PasDB;
integrated security=True;
pooling=False;
multipleactiveresultsets=True;
App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
I see you are using the EDMX with Templates (.tt) for generating the classes. But if you are getting the information from a existing database, the wizard will create a ConnectionString compatible with ObjectContext (metadata informations and provider of entityframework).
The problem is that the connectionstring you are using is for ObjectContext (Database First and Model First). For the DbContext you should use the connectionstring without the metadata informations.
Your connection string should be:
<connectionStrings>
<add name="PasDBEntities"
connectionString="data source=localhost;
initial catalog=PasDB;
integrated security=True;
pooling=False;
multipleactiveresultsets=True;
App=EntityFramework"
providerName="System.Data.SqlClient" />
I'm working through the Building an MVC 3 App with Code First and Entity Framework 4.1 tutorial on MSDN and got stuck on "Also by default, this database will be a SQL Express database with the name derived from the strongly typed name of the context and its file will be in the SQL Express default data folder."
If I want to change the default (e.g. to place the MDF file in my App_Data folder) how would I do that? I will have several different contexts (one for each major functional area) and would like them all to live in the same database.
You define where the database lives using the web.config file connection settings.
You just have to make the Context Name = your connection string name so if the of you Context is MyContext you could define the location as below:
<connectionStrings>
<clear/>
<add name="MyContext"
connectionString="Server=myServer;Database=MyDB;Uid=foo;Password=XXX; "
providerName="System.Data.SqlClient"
/>
</connectionStrings>
In answer to your second question...
"I will have several different contexts (one for each major functional area) and would like them all to live in the same database."
Why not try...
MyContext.cs
public partial class MyContext : DbContext
{
}
FooContext.cs
partial class MyContext
{
public DbSet<Foo> Foos { get; set; }
}
BarContext.cs
partial class MyContext
{
public DbSet<Bar> Bars { get; set; }
}
You'll end up with one context and one connection, but your code is split over multiple files. Hopefully that's what you are trying to achieve.