Build Entity connection string from ADO.NET - c#

In my web site I have regular ADO.NET connection string like:
,
now Entity Framework added it's own connection string to same database.
How is it possible to use only one ADO.NET connection string and build Entity Connection string in runtime?

you can use EntityConnectionStringBuilder to generate connection string at runtime dynamically at runtime but you still need metada for this
EntityConnectionStringBuilder entityBuilder =
new EntityConnectionStringBuilder();
//Set the provider name.
entityBuilder.Provider = providerName;
// Set the provider-specific connection string.
entityBuilder.ProviderConnectionString = providerString;
// Set the Metadata location.
entityBuilder.Metadata = #"res://*/AdventureWorksModel.csdl|
res://*/AdventureWorksModel.ssdl|
res://*/AdventureWorksModel.msl";
using (EntityConnection conn =
new EntityConnection(entityBuilder.ToString()))
{
conn.Open();
Console.WriteLine("Just testing the connection.");
conn.Close();
}

Related

EF6 Passing Connection String to DbContext: System.ArgumentException: 'Keyword not supported: 'provider'.'

I'm trying to pass a connection string to DbContext class through it's constructor but I keep getting this exception. System.ArgumentException: 'Keyword not supported: 'provider'.'
Based on other stackoverflow posts I'm getting the connection string this way.
public string GetConnection()
{
SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder();
sqlBuilder.DataSource = "DataSource";
sqlBuilder.InitialCatalog = "InitialCatalog";
sqlBuilder.UserID = "UserID";
sqlBuilder.Password = "Password";
EntityConnectionStringBuilder entityString = new EntityConnectionStringBuilder()
{
Provider = "System.Data.SqlClient",
ProviderConnectionString = sqlBuilder.ToString()
};
return entityString.ConnectionString;
}
This is what is generated (actual credentials replaced with dummy data)
provider=System.Data.SqlClient;provider connection string="Data Source=DataSource;Initial Catalog=InitialCatalog;User ID=UserID;Password=Password"
This is the DBContext class constructor
public CustomerContext(string connectionString) : base(connectionString)
{
}
For anyone who that might be running into this error. Turns out I had to install the EF6 packages on all projects that were going to reference my repository dll.
Once the packages are installed on all projects that need it, I passed in the connection string only. Without any special formatting or providing the Provider info.
Data Source=DataSource;Initial Catalog=InitialCatalog;User ID=UserID;Password=Password

How to include work station id in entity framework database first model connection string dynamically?

I have a project that uses entity framework data model(.edmx) in it's data layer.I want to add work station id in connection string to store it during create log in database.
This is what I do:
var d = new PresentModelConnectionString();
string connectionString = d.Database.Connection.ConnectionString;
string lastCharacter = connectionString.Substring(connectionString.Length - 1, 1);
if (lastCharacter == ";")
{
connectionString += $"workstation id={Helpers.UserId.ToString()}";
}
else
{
connectionString += $";workstation id={Helpers.UserId.ToString()}";
}
d.Database.Connection.ConnectionString = connectionString;
return d;
But when it tries to connect to database and get data returns The login for user sa failed.When I remove this line:
d.Database.Connection.ConnectionString = connectionString;
It works fine.
This is the connection string:
<add name="PresentModelConnectionString" connectionString="metadata=res://*/PresentModel.csdl|res://*/PresentModel.ssdl|res://*/PresentModel.msl;provider=System.Data.SqlClient;provider connection string="data source=192.168.1.101\sql2014;initial catalog=MIS;user id=sa;password=sa_123;connect timeout=600000000;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
How can I include work station id dynamically to connection string?
Thanks
After searching several hours I found this solution, it change the connection string of entity framework database first model.As Alex recommended in comments I should use SqlConnectionStringBuilder to make connection string.
Create a partial class for model context in a separate file for adding constructor that gives connection string as parameter:
public partial class PresentModelConnectionString
{
public PresentModelConnectionString(string connectionString):base(connectionString)
{
}
}
Make connection string:
//connection string in web.config
//Data Source=192.168.1.101\sql2014;Initial Catalog=MIS_Keshavarzi_980906;user id=sa;pwd=sa_123; Connect Timeout=60000;
string connectionString =
System.Configuration.ConfigurationManager.AppSettings["ABSConnectionString"];
SqlConnectionStringBuilder connectionStringBuilder = new
SqlConnectionStringBuilder(connectionString);
connectionStringBuilder.WorkstationID = Helpers.UserId.ToString(); //get work station id
connectionStringBuilder.ApplicationName = "EntityFramework"; //set application name
For modifying the model connection string use EntityConnectionStringBuilder:
EntityConnectionStringBuilder entityConnectionBuilder = new
EntityConnectionStringBuilder();
entityConnectionBuilder.Metadata =
"res://*/PresentModel.csdl|res://*/PresentModel.ssdl|res://*/PresentModel.msl";
entityConnectionBuilder.Provider = "System.Data.SqlClient";
entityConnectionBuilder.ProviderConnectionString =
connectionStringBuilder.ConnectionString;
PresentModel should change with your model name.
Finally create a new instance of model context with this connection string:
var entityContext = new
PresentModelConnectionString(entityConnectionBuilder.ConnectionString);

connection string to use both Model first, DB first for same database,

In Asp.net Entity framework, we use both Model first, DB first for same database,
And there is two connection string for Model first, DB first.
So how can we create single connection string for both Model first, DB first.
You can use EntityConnectionStringBuilder:
string sqlConnectionString = "Data Source=localhost;
Initial Catalog=AdventureWorks;Integrated Security=True;Connection Timeout=60;multipleactiveresultsets=true"
string providerName = "System.Data.SqlClient";
EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
entityBuilder.Provider = providerName;
entityBuilder.ProviderConnectionString = sqlConnectionString;
entityBuilder.Metadata = #"res://*/AdventureWorksModel.csdl|
res://*/AdventureWorksModel.ssdl|
res://*/AdventureWorksModel.msl";
string entityConnectionString = entityBuilder.ToString();
Or, if you are brave enought, you can try just reformat entityConnectionString:
string sqlConnectionString = "Data Source=localhost;
Initial Catalog=AdventureWorks;Integrated Security=True;Connection Timeout=60;
multipleactiveresultsets=true"
string entityConnectionString =
string.Format("metadata=.\AdventureWorks.csdl|.\AdventureWorks.ssdl|.\AdventureWorks.msl; provider=System.Data.SqlClient;provider connection string='{0}'" providerName=\"System.Data.EntityClient\"",
sqlConnectionString
);
Edit:
Alternatively, you can take oposite approach, lets keep EntityConnectionString and extract SqlConnectionString from it:
string entityConnectionString = 'xxxxxxx';
EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder(entityConnectionString);
string sqlConnectionString = entityBuilder.ProviderConnectionString;
The connection strings will be different: the DB first one will have the metadata [embedded] location at the beginning. You could put the "normal" Code First connection string in the web.config and add the "metadata part" in the DB First DbContext constructor, using a static method to build the EntityConnectionString needed.
Example:
public MyContext() : base(BuildConnectionString())
{
}
private static string BuildConnectionString()
{
varsqlBuilder = new SqlConnectionStringBuilder();
//dinamically prepare the provider connection string here, using the CF one in the web.config
//[..]
//now build the entity connection string, using the one just built as ProviderConnectionString
var entityBuilder = new EntityConnectionStringBuilder();
entityBuilder.ProviderConnectionString = sqlBuilder.ToString();
entityBuilder.Metadata = "res://*/";
entityBuilder.Provider = "System.Data.SqlClient";
return entityBuilder.ToString();
}

Update EF5 Model ConnectionString in Runtime

I have winforms app with SQL Db on my localServer. I added EF5 using Database_First.
The question is:
How to change the connection string of EF5 Model in "Runtime" using "OpenFileDialog"?
I want to provide the app with a "Feature" to let the client specify his Database Server where the app db is located.
There are two problems that need to be considered.
First DbContext has constructor that takes a user defined connection string, but this constructor is not exposed in the generated code for your context, so you have to add it in a partial file outside of the generated code.
And then the Entity Framework connection string itself differs from a typical SqlClient connection string, so you have to use EntityConnectionStringBuilder to build an appropriate connection string.
For example consider this sample code:
public partial class MyContext: DbContext
{
public MyContext(string efConnectionString):base(efConnectionString)
{
}
public static MyContext CreateContextFromAdoCS(string adoConnectionString)
{
EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
//Set the provider name.
entityBuilder.Provider = "System.Data.SqlClient";
// Set the provider-specific connection string.
entityBuilder.ProviderConnectionString = adoConnectionString;
// Set the Metadata location.
entityBuilder.Metadata = #"res://*/MyModel.csdl|
res://*/MyModel.ssdl|
res://*/MyModel.msl";
var efCs = entityBuilder.ToString();
return new MyContext(efCs);
}
}
If you have an existing SqlClient connection string you can use the factory method to create an instance of your context.
Here Display a ConnectionString dialog you can see how to open a standard dialog to construct an SqlClient connection string.
Let it be in App.config
<add name="ConnectionStringNew" connectionString="Data Source=ServerName;user id=sa;Password=sasa;initial catalog=[DataBase]" />
Have a Combobox where you want to let the user to select the DataBase.
FIll the combobox with below coding.
SqlConnection con1 = new SqlConnection (ConfigurationManager.ConnectionStrings["ConnectionStringNew"].ConnectionString);
SqlCommand comm = new SqlCommand("SELECT ROW_NUMBER() OVER(ORDER BY NAME) AS ID,NAME FROM SYS.SYSDATABASES WHERE DBID > 4 ORDER BY NAME", con);
SqlDataAdapter da = new SqlDataAdapter(comm);
da.Fill(dtblDataBase);
cmbDataBase.DataSource = dtblDataBase;
cmbDataBase.ValueMember = "ID";
cmbDataBase.DisplayMember = "NAME";
Replace the DataBase Name Like below.
DataBaseName = Convert.ToString(con1.ConnectionString);
CommonVariables.strDataBaseName = DataBaseName.Replace("[DataBase]", cmbDataBase.Text.Trim());
CommonVariables.strCompanyName = cmbDataBase.Text.Trim();
I have just given a coding sample.. Customize it as you want.

Moving connection string from app.config to code in C#

I'm trying to use Entity Framework and it put it's connection string into app.config. I would like to move it to code as it's easier for me at this stage of development.
metadata=res://*/database.csdl|res://*/database.ssdl|res://*/database.msl;provider=System.Data.SqlClient;provider connection string="data source=computer;initial catalog=database;persist security info=True;user id=user;password=Mabm#A;multipleactiveresultsets=True;App=EntityFramework"
How can I make Entity Framework use connection string from code rather then look at the app.config? Alternatively if it's not possible how can I pass parameters to app.config (like dbname, dbuser, dbpassword)?
You can use EntityConnectionStringBuilder for this purpose.
Check here
public string GetConnectionString()
{
string connectionString = new EntityConnectionStringBuilder
{
Metadata = "res://*/Data.System.csdl|res://*/Data.System.ssdl|res://*/Data.System.msl",
Provider = "System.Data.SqlClient",
ProviderConnectionString = new SqlConnectionStringBuilder
{
InitialCatalog = ConfigurationManager.AppSettings["SystemDBName"],
DataSource = ConfigurationManager.AppSettings["SystemDBServerName"],
IntegratedSecurity = false,
UserID = ConfigurationManager.AppSettings["SystemDBUsername"],
Password = ConfigurationManager.AppSettings["SystemDBPassword"],
MultipleActiveResultSets = true,
}.ConnectionString
}.ConnectionString;
return connectionString;
}
When you create an instance of your ObjectContext derived class, you can simply pass the connection string as a constructor argument.
Rather than use a username and password, why not use Integrated Security? It is more secure and easier to manage.
i.e. 'Trusted_Connection = Yes' in your connection string and securely manage access through AD.
Connection Strings
First, create your context using the constructor with the connectionString parameter.
http://msdn.microsoft.com/en-us/library/gg679467(v=vs.103).aspx
Note that it's not directly this constructor that you must call, but the specific inherited context constructor for your database that your Entity generator created for you.
Furthermore, if you want to pass the username and password at runtime, you can create a connection string using this class:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnectionstringbuilder.aspx
See here:
http://msdn.microsoft.com/en-us/library/bb738533.aspx
If the connection string log in details are always the same then I would suggest that you use ConfigurationManager to retrieve the connection string from your app.config and encrypt the ConnectionStrings section of the file.

Categories