how to switch connection string using switch case and session - c#

my application is like one application with multiple database[all databse are with same schema] i need to switch the connection on dropdown select.i am now managing the all connection string with switch case but now i need to transfer the all connection string to class[.cs] file for globally use in hole app how to do this if session is correct then how to pass string using session to class file and how to retrieve it in hole project
now my cs file is:-
public class connectionstr { static string mulcon = "";
static SqlConnection myconnection = null;
public connectionstr()
{
// // TODO: Add constructor logic here //
}
public static SqlConnection getconnection(string opt)
{
if(opt=="RV001")
{
mulcon = ConfigurationManager.ConnectionStrings["DUM01ConnectionString"].ConnectionString;
}
else if(opt=="SV001")
{
mulcon = ConfigurationManager.ConnectionStrings["CompMasterConnectionString"].ConnectionString;
}
if(myconnection==null)
{
myconnection = new SqlConnection(mulcon);
myconnection.Open();
}
return myconnection;
}
}
but i need to add this in one webform which have dropdown the we shift the connection on dropdown selection and also which connection is selected that that connection is applied with all project webforms

What you essentially need is a single repository for the entire application. You have few options -
Singleton pattern - More details here - Basically you have to implement a singleton class which acts as a store for the connection string. Keep a dictionary in the singleton class. The key in the dictionary will be the user id, and the value will be the selected connectionstring. When the user selects the connectionstring, insert into the dictionary against the user. Wherever he needs a connection, use the connectionstring from the store.
You can do the same by storing the connectionstring in a session variable. As long the user session is valid, you can retrieve it and use it.

Related

SSIS dynamic connection string

I'm trying to make a dynamic connection to DB for all of my packages. I'm trying to achieve this by loading my user defined variables with a Script Component .
I know I can also use environment variables to do this, the problem is that not all of my packages will be scheduled and some of them I run with a web service or a procedure, so I can't use a scheduled job to do this, and using the #reference_id is a bit complicate to maintain.
I have no idea how can I loop the variables. I tried
foreach (Variable var in Variables)
But that's not the way ..
So I have two questions here:
How do I loop all the variables I passed?
How do I get the Variable name out of it ? (I don't see a name attribute on Variables.VarName.?)
E.G. The OLE DB source will return two rows:
conName | conString
con1 | someConnection
con2 | someConnection
And I have two user defined variables in my project -> con1 and con2 .
So, iterate through my varaibles -> foreach(variable) , if var.name = row.conName , load with row.conString value .
Finally I've managed to do this. For those of you who will want to do the same, here is what I did :
public class ScriptMain : UserComponent
{
Dictionary<string, string> AllCons = new Dictionary<string, string>();
public override void PostExecute()
{
base.PostExecute();
string connectionString;
foreach (IDTSVariable100 obj in ReadWriteVariables)
{
if (AllCons.TryGetValue(obj.QualifiedName, out connectionString))
{
obj.Value = connectionString;
}
}
}
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
AllCons.Add("User::" + Row.ConName, Row.ConString);
}
}
I used a Dictionary object to store the connection name and connection string on the Input0_ProcessInputRow section. Then, in the PostExecute, I've iterated through all of my User Defined Variables using an IDTSVariable100 Object. I then checked, if the connection name equals the variable, put the connection string in it.
Hope it helps someone.

When Entity Framework Connection Gets Open & Closed

I have an asp.net web forms application it uses EF for all database activities. When page loads I have to fetch lot of data from different tables. I have a DataAccessor class where I am having a member variable of Entity Framework DbContext (MyDBEntities). See class definition below.
public class DataAccessor
{
public static DataAccessor Instance = new DataAccessor();
private MyDBEntities dbEntities = new MyDBEntities();
private DataAccessor()
{
}
public FetchTable_1_Data()
{
return dbEntities.Table1.Where( x => x.Id = something).List();
}
public FetchTable_2_Data()
{
return dbEntities.Table2.Where( x => x.Id = something).List();
}
public FetchTable_n_Data()
{
return dbEntities.TableN.Where( x => x.Id = something).List();
}
}
Using data accessor as below in page load
Page_Load()
{
Repeater1.DataSource = DataAccessor.Instance.FetchTable_1_Data();
Repeater1.DataBind();
Repeater2.DataSource = DataAccessor.Instance.FetchTable_2_Data();
Repeater2.DataBind();
}
My Questions are,
When DB connection is getting open in my case
When DB connection getting closed?
Do I need to use using(MyDBEntities dbEntities = new MyDBEntities()) instead of using member variable
If i would need to use as question #3, do I need to open connection using "using" statement in each fetch methods?
My database connection is broken sometimes and system performance is getting degrade, i suspect my usage of EF. Can someone advice me how to use EF?
Some more questions,
How connection pooling is working with EF?
connectionString="metadata=res:///ReviewsDb.csdl|res:///ReviewsDb.ssdl|res://*/MyDb.msl;provider=System.Data.SqlClient;provider connection string="data source=SERVER;initial catalog=MyDB;persist security info=True;user id=sa;password=mypwd;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />
I am using above connection string, do I have connection pool with above connection string?
How can I configure connection in EF
Appreciate any help on these questions.
thank you friends
You dataaccessor is a static member.
Stay away from using static since it may survive between page accesses. It is not hard to imagine what damage that could cause.
I have got database errors from the previous page access when I was doing that. I had to scratch my head a lot.
Also use == when comparing instead of =.
You donĀ“t have to use using.
I would actually advise you to have a data accessor that your Page_Load will create with something like var accessor = new DataAccesssor(); instead of using your approach with a private constructor.
Now it will be clear for you which lifetime your MyDbEntities instance will have. It will be scoped to your Page_Load function.

HOW TO: dynamic connection string for entity framework

Like the title. How can I do it?
I tried something, but it doesn't work like I was expecting.
I'm using an Entity Framework model. I need to pass my connection string like parameter, so, in another file, I've written
namespace MyNamespace.Model
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class MyEntities: DbContext
{
public MyEntities(string nameOrConnectionString) : base(nameOrConnectionString)
{
}
}
}
When I startup the app, I call this constructor in this way, so I can refer to this from anyway in the app:
public static MyEntities dbContext = new MyEntities(mdlImpostazioni.SetConnectionString());
where mdlImpostazioni.SetConnectionString() returns a string (the data are correct):
server=192.168.1.100\SVILUPPO;database=MyDB;uid=myName;pwd=111111;
When I execute this code, it seems to be all ok, but when I try to make a query like:
var query = (from r in MainWindow.dbContext.TabTipoSistema select r);
it throws an exception from here:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException(); //exception here
}
So, this is a bad way... which is the right one? (using only code C#, not from xaml)
Your approach is correct, but you need to remember the connection string for EF requires the metadata and so on. So use the EntityConnectionStringBuilder. For example:
// the model name in the app.config connection string (any model name - Model1?)
private static string GetConnectionString(string model, YourSettings settings)
{
// Build the provider connection string with configurable settings
var providerSB = new SqlConnectionStringBuilder
{
// You can also pass the sql connection string as a parameter instead of settings
InitialCatalog = settings.InitialCatalog,
DataSource = settings.DataSource,
UserID = settings.User,
Password = settings.Password
};
var efConnection = new EntityConnectionStringBuilder();
// or the config file based connection without provider connection string
// var efConnection = new EntityConnectionStringBuilder(#"metadata=res://*/model1.csdl|res://*/model1.ssdl|res://*/model1.msl;provider=System.Data.SqlClient;");
efConnection.Provider = "System.Data.SqlClient";
efConnection.ProviderConnectionString = providerSB.ConnectionString;
// based on whether you choose to supply the app.config connection string to the constructor
efConnection.Metadata = string.Format("res://*/Model.{0}.csdl|res://*/Model.{0}.ssdl|res://*/Model.{0}.msl", model); ;
return efConnection.ToString();
}
// Or just pass the connection string
private static string GetConnectionString(string model, string providerConnectionString)
{
var efConnection = new EntityConnectionStringBuilder();
// or the config file based connection without provider connection string
// var efConnection = new EntityConnectionStringBuilder(#"metadata=res://*/model1.csdl|res://*/model1.ssdl|res://*/model1.msl;provider=System.Data.SqlClient;");
efConnection.Provider = "System.Data.SqlClient";
efConnection.ProviderConnectionString = providerConnectionString;
// based on whether you choose to supply the app.config connection string to the constructor
efConnection.Metadata = string.Format("res://*/Model.{0}.csdl|res://*/Model.{0}.ssdl|res://*/Model.{0}.msl", model);
// Make sure the "res://*/..." matches what's already in your config file.
return efConnection.ToString();
}
EDIT
The exception you get is because when you pass a pure SQL connection string, it assumes you are working with Code first, so it calls the OnModelCreation event. When you include the MetaData section as shown above, that tells EF it's a complete EF connection string.
I believe the problem lies on the Datasource you specify. You need to add the port of the connection, e.g if your SQL Server is configured on Port 1433, try:
server=192.168.1.100,1433\SVILUPPO;database=MyDB;uid=myName;pwd=111111;
more details about connection strings you can find Here
Also I am not sure if uid and pwd are valid, better try User ID and Password:
Server=192.168.1.100,1433\SVILUPPO;Database=MyDB;User ID=myName;Password=111111;
Finally mind the case sensitivity.

How to use a dynamic connection string using a Model First approach but still use the data model in the EDMX?

I have created an EDMX using EF 5 with the Model First approach, i.e. I started with a blank designer and modeled my entities. Now I want to be able to use this model defined in the EDMX but supply runtime SQL Server connection strings without modyfing the config file.
I know how to pass a connection string to the DbContext but the issue is locating the metadata for the mappings within the assembly.
For example, my EDMX has this connection string in the app.config
<add name="MesSystemEntities" connectionString="metadata=res://*/Data.DataContext.EntityFramework.MesSystem.csdl|res://*/Data.DataContext.EntityFramework.MesSystem.ssdl|res://*/Data.DataContext.EntityFramework.MesSystem.msl;provider=System.Data.SqlClient;provider connection string="data source=MyMachine;initial catalog=MesSystem;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
The part that I am missing is the "metadata=res://*/Data.DataContext.EntityFramework.MesSystem.csdl|res://*/Data.DataContext.EntityFramework.MesSystem.ssdl|res://*/Data.DataContext.EntityFramework.MesSystem.msl;"
I want to be able to create a DbContext programmatically passing in a SQL Server connection string but "add on" the metadata portion.
This is what I would like to be generated by the T4 file...
public partial class MesSystemEntities : DbContext
{
public MesSystemEntities()
: base("name=MesSystemEntities")
{
}
public MesSystemEntities(string sqlServerConnectionString)
: base(GetEfConnectionString(sqlServerConnectionString))
{
}
private string GetEfConnectionString(string sqlServerConnectionString)
{
// values added by T4 generation
string format = "metadata=res://*/Data.DataContext.EntityFramework.MesSystem.csdl|res://*/Data.DataContext.EntityFramework.MesSystem.ssdl|res://*/Data.DataContext.EntityFramework.MesSystem.msl;;provider=System.Data.SqlClient;provider connection string=\"{0}\"";
return String.Format(format, sqlServerConnectionString);
}
...
}
My question is how can I get the metadata I need in the T4 generation file to create the Entity Framework connection without hardcoding it for each EDMX file
OR
is there an easier way to load the metadata from the assembly programmatically?
I had the same issue, so instead of relying on all the meta data in the connection string (which I think is not a good idea) I wrote a method to create it from a standard connection string. (I should probably refactor it into an Extension method for DbContext, but this should do)
internal static class ContextConnectionStringBuilder
{
// Modified Version of http://stackoverflow.com/a/2294308/209259
public static string GetEntityConnectionString(string ConnectionString,
Type ContextType)
{
string result = string.Empty;
string prefix = ContextType.Namespace
.Replace(ContextType.Assembly.GetName().Name, "");
if (prefix.Length > 0
&& prefix.StartsWith("."))
{
prefix = prefix.Substring(1, prefix.Length - 1);
}
if (prefix.Length > 1
&& !prefix.EndsWith("."))
{
prefix += ".";
}
EntityConnectionStringBuilder csBuilder =
new EntityConnectionStringBuilder();
csBuilder.Provider = "System.Data.SqlClient";
csBuilder.ProviderConnectionString = ConnectionString.ToString();
csBuilder.Metadata = string.Format("res://{0}/{1}.csdl|"
+ "res://{0}/{1}.ssdl|"
+ "res://{0}/{1}.msl"
, ContextType.Assembly.FullName
, prefix + ContextType.Name);
result = csBuilder.ToString();
return result;
}
}
Basic usage is something like:
string connString =
ConfigurationMananager.ConnectionStrings["name"].ConnectionString;
string dbConnectionString = ContextConnectionStringBuilder(connString,
typeof(MyDbContext));
var dbContext = new MyDbContext(dbConnectionString);

LINQ to SQL connectionstring

I have an application that I want to be able to configure the connection string for my LINQ to SQL. I've tried so many different ways but cannot seem to get it working. I want to do this dynamically in the code when the app is run, the reason for this is that the user can change the connection settings.
If I delete the connectionString out of app.config the application still works OK (communicating) which makes me wonder where I should be changing the connection string?
I think that the best way to do it is a combination of Albin's and Rup's answers. Have a value in the config file, and then read it at run time and feed it to the context constructor, something like this:
WEB.CONFIG:
<appSettings>
<add key="ConString" Value="The connection string" />
CODE:
//read value from config
var DBConnString = System.Configuration.ConfigurationManager.AppSettings("ConString");
//open connection
var dataContext= new MyDataContext(sDBConnString)
this way you can change the connection string even at runtime and it will work and change on the running program.
You can pass an override connection string into the DataContext constructor:
var db = new MyDataContext("Data Source=Something Else;")
The DBML class (YourDataContext) has an overloaded constructor which takes ConnectionString, so try instantiating that instead of the default one.Get the connection string from app.config and use that to create the instance.
YourDataContext context = new YourDataContext (ConfigurationManager.ConnectionStrings["ConnStringInAppConfig"].ConnectionString)
You should change it in app.config. The reason it works without is that the LINQ2SQL designer creates a fallback to the connection string used when designing the DBML. If you define a connection string in app.config that is used instead.
By Default your constructor look like this
public dbDataContext() :
base(global::invdb.Properties.Settings.Default.Enventory_4_0ConnectionString, mappingSource)
{
OnCreated();
}
You can change return value Instead of
//Original
public string Enventory_4_0ConnectionString {
get {
return ((string)(this["Enventory_4_0ConnectionString"]));
}
}
this
//Modified code
public string Enventory_4_0ConnectionString {
get {
return (System.Configuration.ConfigurationManager.ConnectionStrings["Enventory_4_0ConnectionString"].ConnectionString);
}
}
Inside your dbml file designer.cs add this dynamic call to base class constructor. It will work for local, dev and prod automatically pulling from current web.config without need to pass connection every time;
public HallLockerDataContext() :
base(ConfigurationManager.ConnectionStrings["MYDB1"].ConnectionString, mappingSource)
{
OnCreated();
}
Usage:
using (var db = new HallLockerDataContext())
{
}

Categories

Resources