Change xpo data model connection string at runtime - c#

I have an application using MSSQLSERVER,when I deploy it to the customer, the server name could change, so I have to change the connection string of my xpo data model at run time,
this is the class generated with the XPO data model
public static class ConnectionHelper {
public const string ConnectionString = #"XpoProvider=MSSqlServer;data source=localhost;integrated security=SSPI;initial catalog=tkdoc";
public static void Connect(DevExpress.Xpo.DB.AutoCreateOption autoCreateOption) {
XpoDefault.DataLayer = XpoDefault.GetDataLayer(ConnectionString, autoCreateOption);
XpoDefault.Session = null;
}
public static DevExpress.Xpo.DB.IDataStore GetConnectionProvider(DevExpress.Xpo.DB.AutoCreateOption autoCreateOption) {
return XpoDefault.GetConnectionProvider(ConnectionString, autoCreateOption);
}
public static DevExpress.Xpo.DB.IDataStore GetConnectionProvider(DevExpress.Xpo.DB.AutoCreateOption autoCreateOption, out IDisposable[] objectsToDisposeOnDisconnect) {
return XpoDefault.GetConnectionProvider(ConnectionString, autoCreateOption, out objectsToDisposeOnDisconnect);
}
public static IDataLayer GetDataLayer(DevExpress.Xpo.DB.AutoCreateOption autoCreateOption) {
return XpoDefault.GetDataLayer(ConnectionString, autoCreateOption);
}
}
I'd like to change the ConnectionString in case the server or the user name or the password change

I suggest that you store the connection string in the application configuration file. This way, users can manually modify it, or you can provide them the special settings form for this purpose.
It is easy to read the connection string from the application configuration file. The code example can be found here on StackOverflow: Get connection string from App.config

Related

How to chose connection string in Entity Framework

I have the following problem: My Program uses an .EDMX model generated from a SQL database with EF on the .NET framework.
When I work on the program at home from my desktop PC, I use Windows authentication. When I open the program at work, it is necessary to build a new .EDMX model with new PC name and standard SQL Server authentication.
How is it possible to change the connection string with a login window for example where I can chose user name, server name and DB name. MS Documentation is not a Help
Thanks for your help
First, you can define the helper to generate a runtime connection string for EDMX. you can find more options for your connection here
public static class Helper
{
public static string GenerateConnectionString(string server, string database, string username, string password)
{
return $"data source={server};initial catalog={database};persist security info=True;user id={username};password={password};" +
$"MultipleActiveResultSets=True;App=EntityFramework"";
}
}
Then add contractor for EDMX Model, for example, my Context model name is [banescoEntities]. "for find context you can type EMDXModelName and use F12 for go to DbContext". shown location on pic. But be careful if you rebuild Model Context, Mabe needs to rewrite code
public partial class banescoEntities : DbContext
{
// add this constractor
public banescoEntities(string connectionString)
: base(connectionString)
{
}
public banescoEntities()
: base("name=banescoEntities")
{
}
// other Context items
}
then create instance like :
internal class Program
{
static void Main(string[] args)
{
// generate ConnectionString runtime
var cs = Helper.GenerateConnectionString("172.31.4.24\\MSSQLSERVER2019", "banesco", "sa", "blablabal");
banescoEntities bsEntities = new banescoEntities(cs);
var products = bsEntities.Products.ToList();
}
}

How to share dynamic connection string name from asp.net application to class libary (data access layer)

I have a ASP.NET Web application project in which when ever user login , according to User logged in, we get have different connection string name from database and store that in session.
In Database access Layer
I have created a class with name ShareSession
public class ShareSession
{
public string ConnectionString1 { get; set; }
public string ConnectionString2 { get; set; }
public ShareSession()
{
try
{
ConnectionString1 = Convert.ToString(HttpContext.Current.Session["ConnectionStringname1"]);
ConnectionString2 = Convert.ToString(HttpContext.Current.Session["ConnectionStringname2"]);
}
catch (Exception)
{
HttpContext.Current.Response.Redirect("~/DashBoard/Login.aspx");
throw;
}
}
}
While accessing this object i just create object of this class.
ShareSession objShareSession = new ShareSession();
var Connection_Database = Convert.ToString(objShareSession.ConnectionString1);
using (SqlConnection conn = new SqlConnection(Convert.ToString(ConfigurationManager.ConnectionStrings[Connection_Database].ConnectionString)))
{
// Database Logic
}
It is performing slow is there any other solution for it.
Scenario:-
i am setting dynamic connection string name from database everytime when use login it has different region database for normalization if one login from india then his data will be inserted in indian database if he login from USA then his data is inserted into USA database , in this condition how can i send this dynamic name of connection to data access layer
Hi there Create a Sealed class for the User and save the connection string there since a sealed class can have only 1 instance(per user) there will not be issue of creating multiple instance to get the same connection string next i would suggest you to pass the connection string as string parameter from BLL to DAL instead of reading it in DAL (just read the connection string from web config to your constructor class of BLL or in DAL your wish )

loading configuration settings from a database

I'm currently writing a MVVMC application in C# (utilising Entity Framework).
What is the correct (best practice) way for loading and storing configuration values?
First of all, there is the question of how to store the configuration settings... would the best way to have the table designed like this: tblConfig(configid, configref, configval) or like this: tblConfig(configid,option1,option2,option3) - replacing option1 etc, with meaningful names (e.g. logoimage)
Next, there is how to retreive/store the settings in the app; My idea was to store the configuration in a table in the database, and then create a static class - something like this:
public static class ConfigClass
{
public static ConfigClass()
{
//load values from database
ContextClass SiteContext = new ContextClass();
logoImage = SiteContext.ConfigSettings.ToList().Find(c => c.configreference == "logoimage").configvalue;
admintoauthoriseaccounts = Convert.ToBoolean(SiteContext.ConfigSettings.ToList().Find(c => c.configreference == "logoimage").configvalue);
defaultaccountrole = Convert.ToInt32(SiteContext.ConfigSettings.ToList().Find(c => c.configreference == "logoimage").configvalue);
}
public static string logoImage = "";
public static bool admintoauthoriseaccounts = true;
public static Int32 defaultaccountrole = 1;
}
Class for the ConfigSetting DbSet Repository:
public class ConfigSetting
{
public string configreference { get; set; }
public string configvalue { get; set; }
}
Is this a good idea? Or should I forget the static class and just read settings directly out of the the DbSet repository?
Thanks.
Most common practice is to store configuration --including the string to connect to that database-- in app.config (or web.config) for the project. Any settings you store in the database would only add the value to, i guess, allow user modification.
If that's your goal:
Store user customization settings in db
Store application config in app.config/web.config
Otherwise:
Store both in app.config.
Serve to the rest of your layers via class, static class, singleton pattern, what have you.
Regardless of that choice:
Best if you do not use static class to hit the database over and over again for settings. This will cause performance degradation.
Branding like a logoimage doesn't sound like something that needs to change often, or per user, and wouldn't really be worth storing in a database.

How do you change SubSonic 3's connection string on the fly?

I want to wrap some queries in a SharedDbConnectionScope and execute them under a different connection string. How do I add a provider/connection string dynamically in order to do this?
Thanks
Both the ActiveRecord\Context.tt and the LinqTemplates\Context.tt that you would use to generate your classes contain constructors:
public <#=DatabaseName#>DB(string connectionStringName)
{
DataProvider = ProviderFactory.GetProvider(connectionStringName);
Init();
}
public <#=DatabaseName#>DB(string connectionString, string providerName)
{
DataProvider = ProviderFactory.GetProvider(connectionString,providerName);
Init();
}
So you can pass your connection string to one of these constructors, like:
// point to a certain connection string in the app.config
var db = new MySample("SomeConnectionStringName");
// Use a specific connection string, not the app.config
var db = new MySampleDB(#"server=.\SQL2008;database=Sample;integrated security=true;", "System.Data.SqlClient");

unable to save settings in app.exe.config

i am facing one problem.
i want to save settings in app.config file
i wrote separate class and defined section in config file..
but when i run the application. it does not save the given values into config file
here is SettingsClass
public class MySetting:ConfigurationSection
{
private static MySetting settings = ConfigurationManager.GetSection("MySetting") as MySetting;
public override bool IsReadOnly()
{
return false;
}
public static MySetting Settings
{
get
{
return settings;
}
}
[ConfigurationProperty("CustomerName")]
public String CustomerName
{
get
{
return settings["CustomerName"].ToString();
}
set
{
settings["CustomerName"] = value;
}
}
[ConfigurationProperty("EmailAddress")]
public String EmailAddress
{
get
{
return settings["EmailAddress"].ToString();
}
set
{
settings["EmailAddress"] = value;
}
}
public static bool Save()
{
try
{
System.Configuration.Configuration configFile = Utility.GetConfigFile();
MySetting mySetting = (MySetting )configFile.Sections["MySetting "];
if (null != mySetting )
{
mySetting .CustomerName = settings["CustomerName"] as string;
mySetting .EmailAddress = settings["EmailAddress"] as string;
configFile.Save(ConfigurationSaveMode.Full);
return true;
}
return false;
}
catch
{
return false;
}
}
}
and this is the code from where i am saving the information in config file
private void SaveCustomerInfoToConfig(String name, String emailAddress)
{
MySetting .Settings.CustomerName = name;
MySetting .Settings.EmailAddress = emailAddress
MySetting .Save();
}
and this is app.config
<configuration>
<configSections>
<section name="MySettings" type="TestApp.MySettings, TestApp"/>
</configSections>
<MySettings CustomerName="" EmailAddress="" />
</configuration>
can u tell me where is the error.. i tried alot and read from internet. but still unable to save information in config file..
i ran the application by double clicking on exe file also.
According to the MSDN: ConfigurationManager.GetSection Method,
The ConfigurationManager.GetSection method accesses run-time configuration information that it cannot change. To change the configuration, you use the Configuration.GetSection method on the configuration file that you obtain by using one of the following Open methods:
OpenExeConfiguration
OpenMachineConfiguration
OpenMappedExeConfiguration
However, if you want to update app.config file, I would read it as an xml document and manipulate it as a normal xml document.
Please see the following example:
Note: this sample is just for proof-of-concept. Should not be used in production as it is.
using System;
using System.Linq;
using System.Xml.Linq;
namespace ChangeAppConfig
{
class Program
{
static void Main(string[] args)
{
MyConfigSetting.CustomerName = "MyCustomer";
MyConfigSetting.EmailAddress = "MyCustomer#Company.com";
MyConfigSetting.TimeStamp = DateTime.Now;
MyConfigSetting.Save();
}
}
//Note: This is a proof-of-concept sample and
//should not be used in production as it is.
// For example, this is not thread-safe.
public class MyConfigSetting
{
private static string _CustomerName;
public static string CustomerName
{
get { return _CustomerName; }
set
{
_CustomerName = value;
}
}
private static string _EmailAddress;
public static string EmailAddress
{
get { return _EmailAddress; }
set
{
_EmailAddress = value;
}
}
private static DateTime _TimeStamp;
public static DateTime TimeStamp
{
get { return _TimeStamp; }
set
{
_TimeStamp = value;
}
}
public static void Save()
{
XElement myAppConfigFile = XElement.Load(Utility.GetConfigFileName());
var mySetting = (from p in myAppConfigFile.Elements("MySettings")
select p).FirstOrDefault();
mySetting.Attribute("CustomerName").Value = CustomerName;
mySetting.Attribute("EmailAddress").Value = EmailAddress;
mySetting.Attribute("TimeStamp").Value = TimeStamp.ToString();
myAppConfigFile.Save(Utility.GetConfigFileName());
}
}
class Utility
{
//Note: This is a proof-of-concept and very naive code.
//Shouldn't be used in production as it is.
//For example, no null reference checking, no file existence checking and etc.
public static string GetConfigFileName()
{
const string STR_Vshostexe = ".vshost.exe";
string appName = Environment.GetCommandLineArgs()[0];
//In case this is running under debugger.
if (appName.EndsWith(STR_Vshostexe))
{
appName = appName.Remove(appName.LastIndexOf(STR_Vshostexe), STR_Vshostexe.Length) + ".exe";
}
return appName + ".config";
}
}
}
I also added "TimeStamp" attribute to MySettings in app.config to check the result easily.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="MySettings" type="TestApp.MySettings, TestApp"/>
</configSections>
<MySettings CustomerName="" EmailAddress="" TimeStamp=""/>
</configuration>
In many cases (in a restricted user scenario) the user do not have write access directly to the application config file. To come around this, you need to use the usersettings.
If you right-click your project and select the tab named "Settings", you can make a list of settings that are stored with the config file. If you select the "Scope" to be "User", the setting are automatically stored in the config file using a type that will automatically store the settings under the users AppData area, where the user allways has write access. The settings are also automatically provided as properties created in the Properties\Settings.Designer.cs code file, and are accessible in your code in Properties.Settings.Default .
Example:
Let's say you add a user setting called CustomerName:
On loading the app, you would want to retreive the value from the stored setting ( either default value as it is in the app config, or if it is stored for this user, the config file for the user):
string value = Properties.Settings.Default.CustomerName;
When you want to change the value, just write to it:
Properties.Settings.Default.CustomerName = "John Doe";
When you want to save all the settings, just call Save:
Properties.Settings.Default.Save();
Note that when you develop, the user file will occationally be reset to the default, but this only happens when building the app. When you just run the app, the settings you store will be read from the user-config file for the app.
If you still want to create your own handling of the settings, you can try this once, and look at what VisualStudio has automatically created for you to get an idea of what you need to get this working.
In order to actually update the config file, you'll need to call .Save() on the Configuration object - not just your config section object.
You should check out Jon Rista's three-part series on .NET 2.0 configuration up on CodeProject.
Unraveling the mysteries of .NET 2.0 configuration
Decoding the mysteries of .NET 2.0 configuration
Cracking the mysteries of .NET 2.0 configuration
Highly recommended, well written and extremely helpful! It shows all the ins and outs of dealing with .NET 2.0 and up configuration, and helped me very much getting a grasp on the subject.
Marc
Be aware that the appname.vshost.exe.Config is reverted to it's the original state at the end of the debugging session. So you might be saving to the file (you can check by using Notepad during execution), then losing the saved contents when the debugging stops.

Categories