Changing Nhibernate Connectionstring - c#

simple question how do i change the connection string of the nhibernate at runtime ?
<property name="connection.connection_string" >value</property>

nevermind i got it.
Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var root = XElement.Load(configuration.FilePath);
root.Elements().Where(m => m.Name.LocalName == "hibernate-configuration").First().Elements().First().Elements().Where(m => m.FirstAttribute.Value == "connection.connection_string").First().Value = cs;
root.Save(configuration.FilePath);

Tinkering with your app.config on the fly is a bit horrible.
I'd suggest not storing your connection string amongst the other nhibernate settings. Keep your various connection strings elsewhere (e.g. in appSettings), then set the appropriate connection string directly against your NH Configuration:
var configuration = new Configuration();
configuration.SetProperty("connection.connection_string", "...connection string...");
configuration.Configure();
Just make sure that the connection.connection_string setting is not specified in your config file, as configuration.SetProperty will only work correctly if the setting is not there already.

When you need to switch connections based on some conditions (such as having one website with live and demo mode, each with different connection string) then it´s probably best to implement a class inherited from DriverConnectionProvider and set this class as value of the connection.provider configuration property in your config file.
See http://jasondentler.com/blog/2009/11/authentication-impersonation-and-dynamic-nhibernate-connection-strings/

I would personally go with Enterprise Library and its Data Access Application Block to provide the NHibernate sessions APIs with proper named connectiong strings when instantiating a session API.
The DAAB has the feature to instantiate a DbConnection based on the configuration file. So you could possibly use several connection strings definition, and tell DAAB what connection to use, then pass it to your NHibernate session so that you may work with NHibernate against multiple datastores at once.
Using this approach will avoid you messing with the configuration file on runtime, and even allows you to create your own connections instance without having them defined in the configuration file at once.

Related

Change connString dynamically

I am currently working on an ASP.NET MVC project with Entity Framework. The solution includes the ASP.NET MVC application and a DataProvider project. The project only includes an EF model, as I have a partner who shares a database with me.
The problem is in that, that we don't actually share the same database. What I mean is that the actual server of the database is not the same. We have the same tables. But the connection string has to be changed every single time we pull from our git repository. The string changes in the web.config file of the ASP.NET MVC project and in the app.config file of the EF library.
My question is - if there is a way for our system to detect which PC it is running on and modify the connection string dynamically? Now I do it manually.
<!--PC NICO CEI-->
<!--
<connectionStrings>
<add name="dbShubertEntities"
connectionString="metadata=res://*/ModelDbShubert.csdl|res://*/ModelDbShubert.ssdl|res://*/ModelDbShubert.msl;provider=System.Data.SqlClient;provider connection string="data source=E04\SQLEXPRESS;initial catalog=dbShubert;user id=gereisma17;password=12321;MultipleActiveResultSets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
-->
<!--PC NICO Laptop-->
<!--
<connectionStrings>
<add name="dbShubertEntities"
connectionString="metadata=res://*/ModelDbShubert.csdl|res://*/ModelDbShubert.ssdl|res://*/ModelDbShubert.msl;provider=System.Data.SqlClient;provider connection string="data source=DESKTOP-I62BLOC;initial catalog=dbShubert;user id=user;password=1234;MultipleActiveResultSets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
-->
This is what I do now. I am commenting the connection string. I want to automate the whole thing.
You could overload the DbContext's constructor with the dynamic connection string
public class MasterDal : DbContext
{
public MasterDal(string nameOrConnectionString) : base(nameOrConnectionString)
{
}
// DbSet & OnModelCreating etc
}
& then invoke dal in Controller as required
if (logicToGetPc.equal("CEI"))
{
MasterDal dal = new MasterDal("dbShubertEntitiesCEI");
// do mumbai related whatever
}
else if (logicToGetPc.equal("Laptop"))
{
MasterDal dal = new MasterDal("dbShubertEntitiesCEILaptop");
}
if you are using aspnet core there is a way to configure environment variable as override for the app settings
this way you'll have a "default" appsettings.json that contains all the common settings, then on the different machine you can configure environmnet variables that replaces (override) the connection string in different way for each machine
i suppose a similar approach is possible for aspnet for the full framework as well
as your connection string have already a quite specific name "dbShubertEntities" it sould be quite effective to override and you should not risk to have connection string collisions in case you work on different projects.
as reference see https://joonasw.net/view/asp-net-core-1-configuration-deep-dive the part where it uses .AddEnvironmentVariables()
Store the connection string as an environment variable on each PC.
When creating the connection to the database, retrieve the connection string using Environment.GetEnvironmentVariable method instead.
(at time of writing, there's no code)
This is what appsettings.json, (or it's counterparts), was made for.
As i perceive your predicament, (you need more whitespace in your writing to make it easier to read), you are basically working in two different environments, (similar to dev versus test). A simple configuration change would be the simplest way.
As an aside:
Reading between the lines, it seems like you are hard-coding connection strings, and I have a two-word advice for you: STOP IT! (I used to do that, and It's a bad habit that can be hard to shake off)

How to add connection string to once for whole solution to use?

Recently I am working on an .Net project. We used EF to handle SQL, when we make an installer of the program, we realize that app.config is visible which mean that the connection string is not safe.
I am looking for a way to add connection string (or maybe secret code and username) to the EF so that the connection string is not visible.
Something like change old code from this
Using db As ConnectDb.adoSentoEntities= New ConnectDb.adoSentoEntities
'TODO
End Using
to this
Using db As ConnectDb.adoSentoEntities= New ConnectDb.adoSentoEntities(ConnectionString)
'TODO
End Using
But since we used connect code to SQL all over the place, changing every single line of code is not possible. There is a way I only need to add connection string once?
You’d be better off encrypting the connection string section in the app.config. You wouldn’t need to make any changes.
Storing any sort of configuration in an assembly can be read using a hex editor.
It’s been answered on here before.
Encrypting Connection String in web.config
You’d be better off using a trusted connection if you’re using SQL Server. The user running the app would need to have permissions and no username and password is required.
Save connection string is settings of project properties.
Go in project properties.
Select settings.
Add new setting as connection string and save connection string.
Then you can use it for whole project.

How to create dynamic database connection string C#

I just created a desktop Winforms application with localhost database.
The connect string I am using is this:
SqlConnection connect = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\Administrator\Desktop\learningsystem\LearningSystem\LearningSystem\LearningSystem.mdf;Integrated Security=True");
If I want to run my application on other computers, how should I make it work?
EDIT:SOLUTION
Thank for all the help! I tried the following steps. I think it is working now. But please correct me if I did something tricky.
1. add a new setting item in project property setting. App.config will automatically update:
<connectionStrings>
<add name="LearningSystem.Properties.Settings.LearningConn" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\LearningSystem.mdf;Integrated Security=True;Connect Timeout=30"
providerName="System.Data.SqlClient" />
</connectionStrings>
2. In my program, just add the following statement to connect to the sql server
SqlConnection connect = new SqlConnection(#"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename=|DataDirectory|\LearningSystem.mdf;Integrated Security = True; Connect Timeout = 30");
Further question
If others will run this application on their computer(not in the same network), they just go into the project setting and change the value by selecting the database file I provide to them,the connectionString will automatically change, right?
Thanks!
It's generally a bad idea to hard code such stuff in your application. Normally, application settings and connection strings are placed in the application's configuration file (in the ConnectionStrings section).
Just like with all strings, you could build your connectionstring from dynamic parts (variables, settings, etc.) and then pass that generated connectionstring to the SqlConnection constructor. Again, to make those separate parts configurable without hard coding them in your application, you might want to add them to your application's configuration file (in the AppSettings section). But IMHO this is an overly complex solution in most scenarios. Putting the entire connectionstring in the ConnectionStrings section is more straightforward (and more flexible).
Anyway, again, to make your application configurable, you might use your application's configuration file (App.config or Web.config), you need to add a reference to System.Configuration in your project's .NET Framework dependencies and use the AppSettings and ConnectionStrings properties of the System.Configuration.ConfigurationManager class.
(Of course, there are more ways to make your application configurable. But using the application configuration file is one of the most straightforward solutions.)
Edit:
When deploying your app to another computer, you need to copy its database over too. If you want to use the application on multiple machines and let them connect to the same database, you might want to leave LocalDB and migrate the data to a SQL Server (Express) instance and make it accessible over the (local) network.
Edit 2 (regarding the recent edits in your post):
I see in step 1 that you are using an application setting (called LearningConn) in your solution now. That's fine. However, it is important that you also use that setting in step 2, like this:
SqlConnection connect = new SqlConnection(Properties.Settings.Default.LearningConn);
If you change the setting in Visual Studio, it will update the connection string. Since the setting will probably have application scope, it will not be possible to update the setting/connection string within your application in runtime (by the user).
I'm not sure if your connection string using |DataDirectory| will always work as expected in all scenarios. I have only been using it in ASP.NET webapplications. If it does work in WinForms applications, you might read this document to learn how to set it up. But personally I am somewhat sceptical about this approach.
I personally would opt for a solution where you use a placeholder in your connection string, which you replace with the full path to the .mdf file before you pass it to your SqlConnection constructor.
When you use "{DBFILE}" as the placeholder, for example, the value of your LearningConn setting would look like this:
Data
Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename={DBFILE};Integrated
Security=True;Connect Timeout=30
(Note that this value should be a single line without any line breaks!)
You might create a separate setting in your application called DbFile (of type string) to store the actual value that should be put in place of {DBFILE} in your connection string. When you use scope "user" for that setting, the value might be changed from within the application by the user. When saved, it might not be saved directly in the application's configuration file, however, but in an additional configuration file hidden somewhere in the user's Windows user profile. You might read this document to learn more about application settings.
Your code in step 2 might eventually look something like this:
string connectString = Properties.Settings.Default.LearningConn;
string dbFile = Properties.Settings.Default.LearningSystemDb;
connectString = connectString.Replace("{DBFILE}", dbFile);
SqlConnection connect = new SqlConnection(connectString);
To let your application's users select and store the database .mdf file to use, you might include (a variation of) the following code in your application somewhere:
using (var dlg = new System.Windows.Forms.OpenFileDialog())
{
dlg.Title = "Select database file to use";
dlg.Filter = "Database Files (*.mdf)|*.mdf";
dlg.CheckFileExists = true;
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Properties.Settings.Default.DbFile = dlg.FileName;
Properties.Settings.Default.Save();
}
}
Your question is not clear!
you need work with one Database on 2 or more PC?!
OR
you need work with 2 separate programs?
if you need 2 separate programs :
you must copy .mdf file to other PC at same address or keep mdf address in app.config and read it before connect to SQL.
How to Read From app.config
if you need work with one Db you must connect to dataBase Server such as SQL Server and keep connection string in app.config in connectionStrings tag.
Get connection string from App.config
If you want to work on other PCs, rather than building it dynamically make the connection string more generic:
Server=(localdb)\\mssqllocaldb;Database=LearningSystem;Trusted_Connection=True;MultipleActiveResultSets=true
This should create the mdf file under 'mssqllocaldb' in %appdata% for each user. You might need LocalDb installed (which you tick during SQL Server installation)

Dynamically change connection string for SessionManger without using factoryalias

I am trying to use nHibernate and Castle and make a connection to one database based on the connection string stored in another database. Is there any way to change the connection string for SessionManager dynamically?
the connectionstring is baked into the sessionfactory. i doubt that you can change it. you could create a lightweight factory to get the connection string or just use ADO.NET directly and then build up the real factory.

What is preferred method for modifying connection string settings in DAL class library when deploying asp.net web app?

I deployed my asp.net web app project that has a reference to my DAL class library. How can I change the connection string in my DAL library once deployed? The DAL code was ignoring my web.config connection string and trying to use the app.config value.
I thought I would be able to edit a config file that is associated with the class library, but I can't find one. Temporarily I edited the connection string and re-compiled and re-deployed the library.
Is there an option or way to setup the project files where it changes the values of the connection string based on being compiled in debug mode versus doing a release compile.
What is the recommended way of dealing with connection strings in web apps which reference class libraries?
Clarification:
the DAL library connection strings are also utilized by some datasets and L2S classes (.dbml) and I am not sure how to change those to reference a web.config file that sits outside the library in the web app project.
Currently Using this code to get around my L2S class problem:
public partial class MyDataContext
{
partial void OnCreated()
{
ConnectionStringSettings cs = ConfigurationManager.ConnectionStrings["PrimaryConnectionString"];
if (cs != null)
{
this.Connection.ConnectionString = cs.ConnectionString;
}
}
}
Generally, I let the top-level project define this, via either web.config or app.config; either by specifying that the application should include a connection-string named "FOO", or (much better) allowing the calling application to pass (one of) the connection key, the connection string, or the connection to the dll.
Then you mainly just edit web.config like normal...
I usually place the string in the web.config file and let a class (possibly a global class used to reference settings in the web.config) reference it, with the following line:
class Globals
{
static string ConnectionString =
ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString;
}
and use it elsewhere like:
IApartmentRepository apartmentRepository = new
ApartmentRepository(Globals.ConnectionString);
This was also Saif Khan's suggestion in his answer.
As for changing the connection strings based on compile mode, Visual Studio 2010 has support for this, see Web Deployment: Web.Config Transformation from the Visual Web Developer team blog. I do not think Visual Studio 2008 can do this out of the box, however maybe it can be done with some kind of build script.
I don't believe there is a recommended way, but a prefered way. Some store connection strings in the web.config file, while some store in the registry or machine.config, while some go to the extreme and store it remotely...yes I've seen that.
The most common storage I see and use myself is storing in the web.config. In my DAL objects I make a call to the web.config file for the connectionstring
string connStr = ConfigurationManager.ConnectionStrings["myString"].ConnectionString
as for auto changing of the connectionstring based on the app compiled mode, I've never seen that. You might have to put that check in the DAL itself to check if debug mode is turned "on" or "off". That would require 2 connectionstring entries in the web.config file.

Categories

Resources