C# Entity Framework Reconnecting to the database by new connection - c#

1 Run Application
2. Create Context
dbContext = new DBFirstContext();
3 Change App.config connection string for Entity FrameWork Object
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// change ConnectionString in App.Config for Entity FrameWork Object....
//.....
config.Save();
ConfigurationManager.RefreshSection("connectionStrings");
And now if I create
dbContext = new DBFirstContext();
It use sourse unchanged connectionString, as it was at starting application. If Close and then restart the application - new dbContext will be created by using modified connectionString.
PS: I don't want to passing new connection string for create new dbContext by using constructor like this:
public DBFirstContext(string sConnectionString)
: base(sConnectionString)
I need to create dbContext by using default constructor, and that it take a new (changed) connection string from the app.config without restarting the application. Is it possible?
Thank!

The App.config is read and parsed only once.
See the answer of "Darin Dimitrov" that was marked as the final answer. Why my changes of AppSettings in App.config is not taken into account in run-time? (Console Application)
I only take credit for Googling for this answer. All other credit should go to Darin.
In short: you're trying to use someting in a way it's not meant to be used. What is the reason you only want to work with the default constructor?

It is unclear why you need to change app.config or your connection string at runtime, but one way to change the connection string of your context without reconstructing it, is the following:
context.Database.Connection.ConnectionString = "connection string here";
Of course, your connection string must respect the format required by EF, so one way to construct your connection string is:
String.Format(
#"metadata=res://*/DBFirstContext.csdl|res://*/DBFirstContext.ssdl|res://*/DBFirstContext.msl;provider=System.Data.SqlClient;provider connection string='{0}'", connString);
where connString is a SQL Server connection string

my solution How to use default constructor for create context object by using connectionString from curent App.Config (App.Config were edited at run-time)
public DBFirstContext()
: base(System.Configuration.ConfigurationManager.ConnectionStrings["DBFirstContext"].ConnectionString)
{
}

Related

Change connection string at runtime MySql C#

i have an app.config file that has a connection string for my database.
what i want to do is to connect to different databases that's why i used to this code:
connectionString = "Data Source=blah;Initial Catalog=blah;UID=blah;password=blah";
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var connectionStringsSection = (ConnectionStringsSection)config.GetSection("connectionStrings");
connectionStringsSection.ConnectionStrings[nameofConnectionString].ConnectionString = connectionString;
config.Save();
ConfigurationManager.RefreshSection(nameofConnectionString);
it works well, it changed the connection string, but the problem is that it sends me an error saying "facerec6.0.cdcol does not exist"
my default initial catalog = facerec6.0
what will i do ?
The ConnectionStringSection is just a container to store named connection strings. If you want to connect to different databases then it's best to start by storing those different connection strings in that section from the start and then determining how your application will choose which one to use at runtime.
Think of that section as just that and nothing more - it's a convenient, known place to store connection strings with a standard way to retrieve them. Other developers working on the code will know where to look for them and know how to retrieve them.
Even though it's technically possible to modify that section at runtime and save the file I wouldn't do that. If you have the same code that may use different connection strings while running in the same environment (it's not a case of one for development, one for QA, and one for production) then you could have your class depend on an interface something like this:
public interface IConnectionStringFactory
{
string GetConnectionString(Something key);
}
Where Something is a value that the class requiring the connection string can pass to the factory, and the factory can use it to determine which connection string to retrieve. That way the class that uses the connection string is insulated from that logic. It doesn't know why it uses one connection string or another. It just gets a connection string from the factory and then uses it.
If it's a case of varying connection strings by environment then that's much, much easier - you can do that with config transforms. In most cases if it's a different environment then all the connection strings will be different for each environment, so you can just replace the whole section.
<connectionStrings xdt:Transform="Replace">
<add name="connectionStringA" connectionString="...whatever..." />
</connectionStrings>
Please try this instead:
ConfigurationManager.RefreshSection("connectionStrings");
because:
<connectionStrings> <- this is the section
<add name="facerec6.0"/> <- this is the element
<add ... />
</connectionStrings>
You need to refresh the section, not the element, when using RefreshSection.

Entity Framework - Invalid Object with custom connections string

Just for a brief overview this is how I added the database into my project:
I have added a datasource by adding an ADO.NET Data Model Entity and selecting EF Designer from Database.
Doing so has generated a connection string for me in my web.config. Integrated Security is set to true (if that matters).
Once connected I right clicked and selected 'Update model from database.
Since there is multiple environments I built a custom context with a parametized constructor. Code looks as such (condensed and censored):
public partial class DataEntities : DbContext
{
public DataEntities(string connectionString)
: base(connectionString)
{
}
}
With each environment there are different local sql accounts associated. Requiring me to generate a connection string that is associated with the correct account in the correct environment. Doing so my web config looks something like this:
<connectionStrings>
<add name="DataEntities" connectionString="metadata=res://*/Models.XXModel.XXModel.csdl|res://*/Models.XXModel.XXModel.ssdl|res://*/Models.XXModel.XXModel.msl;provider=System.Data.SqlClient;provider connection string="data source=MYSQLSERVER;initial catalog=Data;integrated security=True;MultipleActiveResultSets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
<secureConnectionStringsSection passwordPolicy="AllowLocalPasswordsForConnectionStrings">
<secureConnectionStrings>
<add name="DataEntities-Local" providerName="System.Data.SqlClient" connectionString="data source=MYSQLSERVER;user id=ACCNT; password=PASSWORD;" />
</secureConnectionStrings>
</secureConnectionStringsSection>
When I am instantiating my DataEntity object, I am calling a helper function I have written to get my custom connection string. I am doing so via the following code:
private DataEntities adDB = new DataEntities(XXX.Helpers.EFDBHelper.getDataConnectionString());
I can verify that my connection string helper does correctly pull the custom connection string that I have in my web.config. However once I actually try to make a call on the database I am left with the following error:
Invalid object name 'dbo.mycolumn'.
I know that my parametized constructor is being called with the correct connection string. I also know my connection string is valid, I have tested it in powershell:
$conn = New-Object System.Data.SqlClient.SqlConnection
$conn.ConnectionString = "data source=MYSQLSERVER;user id=ACCNT;password=PASSWORD"
$conn.Open()
$conn.Close()
I am certain that it is not an issue with the database itself as well. The moment I remove the parameter from my Entity initialization:
private DataEntities adDB = new DataEntities();
I am able to pull data from the database. I am assuming that it uses the auto-generated connection string. Which won't work since I cannot use integrated security once it goes past my local environment.
My apologies, I am new to the technology here. I am sure that it is just something small that I am missing.
In my connection string I did not specify a catalog.
Since I am newish to the technology, I tried to simply replicate some of the existing code that I had inherited. In the connection string I tried to replicate from, no catalog was expressed as well.
However... the account I am using to talk to the new datasource has access to all levels of the database so the catalog was required. The old inherited database had only one catalog the the sql account had access too.
You live and you learn!

EF migrations need default ctor, however, I don't know the connection string?

EF code first migrations require me to put a default constructor on my DbContext class, this requires me to know the exact connection string - however, I don't know the connection string yet.
My context and the entities reside in a MyProject.Data assembly with no information about the actual database whatsoever. The connection string is in the MyProject.Executable's app.config file. Still I want to put all the migrations into the MyProject.Data project, because that is where they belong.
Is there any way to do EF migrations without having a default CTOR, etc.?
If the connectionstring is in the app.config/Web.config of your main project (the one you will be building), you can use ConfigurationManager.ConnectionStrings to retrieve them.
If you are wondering how it will work if it's in a different project: This will only be executed at runtime. At runtime, your projects have been compiled into one big application, and everything listens to the same app.config/Web.config file (the one that was in your startup project when you built it).
From the link:
var connectionString =
ConfigurationManager.ConnectionStrings["WingtipToys"].ConnectionString;
using (var connection = new SqlConnection(connectionString))
{
//...
}
The same applies for any constructor where you need to know the connectionstring, like your DBContext.
According to this SO answer, you only need to pass the name of your connectionstring, so that means you don't even need to use ConfigurationManager.
From the linked answer:
After reading the docs, I have to pass the name of the connection string instead:
var db = new NerdDinners("NerdDinnerDb");
You can refer to the name of connection string placed in your default start up project. This is why parameter of DbContext constructor is nameOrConnectionString.
public class MyContext : DbContext
{
public MyContext()
: base("Name=NameOfConnectionString")
{
}
}

Entity Framework Connection String Trouble

I am making a little library(DLL) to manage users and their roles/privileges. The plan is to be able to add this dll to an MVC project and be able to manipulate users/roles/etc. All the data resides in a SQL db.
I am using entity framework for data access.
So when I initialize a new RoleManager(this is the name of the main class in the lib I'm making) I supply it with a connectionString like so:
RoleManager roleManager = new RoleManager(string connectionString);
Then inside the constructor I do this:
db = new RoleManagerEntities(connectionString); //This is the EntityFramework
And I am trying to supply this connection string (among many others)
"metadata=res://*/RoleManager.csdl|res://*/RoleManager.ssdl|res://*/RoleManager.msl;provider=System.Data.SqlClient;provider connection string='Data Source=localhost;Initial Catalog=Login;Integrated Security=True;Connection Timeout=60; multipleactiveresultsets=true'"
And I get the following error:
The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid.
This question is a result of having trying to instantiate the EF from my new project without supplying a connection string and without having anything inside my app config for it to default to. Too bad I can't delete it now.
Just copy the connection string information from your DLL config file to your executable config file.
Basically you are trying to instantiate an ObjectContext via this ObjectContext Constructor (String) without passing the string parameter in its expected format and that's the problem.
Here is what you need to do:
1. First create an entry in your in your "test project" app.config because that is the place that the CLR is looking at to find the connection string at runtime.
<configuration>
<connectionStrings>
<add name="RoleManagerEntities" connectionString="metadata=res:///RoleManager.csdl|res:///RoleManager.ssdl|res://*/RoleManager.msl;provider=System.Data.SqlClient;provider connection string='Data Source=localhost;Initial Catalog=Login;Integrated Security=True;Connection Timeout=60; multipleactiveresultsets=true'" />
</connectionStrings>
</configuration>
2. Now change the code to pass the connection string name instead of the actual connection string:
db = new RoleManagerEntities("name=RoleManagerEntities");
The constructor might be looking for a connection string in the connectionStrings setting of your web.config with the name that you pass it as the parameter.
So if you call:
db = new RoleManagerEntities("Foobar");
It is looking for:
I'm not positive that this is the solution but that's what the error message seems to indicate.
I am not an expert on EF, but I don't think that connection string is valid. Try:
metadata=res://*;provider=System.Data.SqlClient;provider connection string='Data Source=localhost;Initial Catalog=Login;Integrated Security=True;Connection Timeout=60; multipleactiveresultsets=true'

Is there a way to load an existing connection string for Linq to SQL from an app.config file?

I'm running into a really annoying problem with my Linq to SQL project. When I add everything in under the web project everything goes as expected and I can tell it to use my existing connection string stored in the web.config file and the Linq code pulls directly from the ConfigurationManager.
This all turns ugly once I move the code into its own project. I’ve created an app.config file, put the connection string in there as it was in the web.config but when I try to add another table in the IDE keeps forcing me to either hardcode the connection string or creates a Settings file and puts it in there, which then adds a new entry into the app.config file with a new name.
Is there a way keep my Linq code in its own project yet still refer back to my config file without the IDE continuously hardcoding the connection string or creating the Settings file? I’m converting part of my DAL over to use Linq to SQL so I’d like to use the existing connection string that our old code is using as well as keep the value in a common location, and one spot, instead of in a number of spots.
Manually changing the mode to WebSettings instead of AppSettings works untill I try to add a new table, then it goes back to hardcoding the value or recreating the Settings file. I also tried to switch the project type to be a web project and then rename my app.config to web.config and then everything works as I’d like it to. I’m just not sure if there are any downfalls to keeping this as a web project since it really isn't one. The project only contains the Linq to SQL code and an implementation of my repository classes.
My project layout looks like this
Website
-connectionString.config
-web.config (refers to connectionString.config)
Middle Tier
-Business Logic
-Repository Interfaces
-etc.
DAL
-Linq to SQL code
-Existing SPROC code
-connectionString.config (linked from the web poject)
-app.config (refers to connectionString.config)
Update
Here's an example of the code I'm talking about
Web Project
public DB() :
base(global::System.Configuration.ConfigurationManager.ConnectionStrings["SiteSqlServer"].ConnectionString, mappingSource)
{
OnCreated();
}
Non Web Project
public DB() :
base(global::SampleProject.Data.Properties.Settings.Default.SiteSqlServer, mappingSource)
{
OnCreated();
}
Every time I try to make the default constructor look like the first way, it always auto changes back to the second way once I make a change to the file unless the DBML is inside of a web project.
i use a trick for this:
public partial class DataContext
{
partial void OnCreated()
{
this.Connection.ConnectionString =
global::System.Configuration.ConfigurationManager
.ConnectionStrings["SQLServer"].ConnectionString;
}
}
this will read the connection string out of the current configuration manager, which (in the case of an ASP.Net website) will be the Web.config. I just add this partial class definition to the same project where my dbml is defined. Then any other project that uses the dbml project will just have to define their connection strings in their app.config/web.config.
you need to create a new partical class DataContext like this
public partial class DataContext
{
partial void OnCreated()
{
this.Connection.ConnectionString =
ConfigurationManager.ConnectionStrings["MyDBConnectionString"].ConnectionString;
}
}
and it will automatically read your connection string automatically from web.config file for more detail see Linq to SQL connection String to read from web.config file automatically
If you mean: Can I use a particular connection string in Linq-2-Sql? Then the answer is yes.
When you instantiate the DataConext you can pass in a connection string which can come from where-ever you like.
If you wanted to use the connection string configured in your Linq project then you could create your own Settings class and add it there and reference it via code in your Linq project.

Categories