Entity Framework changing connection string with c# - c#

I have an app that the connection string changes by per user and machine. that said I have made a test connection string just to get it testing. Then once that is working I will add the dynamic connection string.
After some research I have figured out that there is a problem with the connection string.
If someone could please tell me where I am wrong I would appreciate it.
var s = #"metadata=res://*/ProcurementModel.csdl|res://*/ProcurementModel.ssdl|
res://*/ProcurementModel.msl;provider=System.Data.SqlClient;
provider connection string=&';data source=JAMES-DESKTOP\SQLEXPRESS;initial catalog=MyDatabase;persist security info=True;user id=User;password=*****;MultipleActiveResultSets=True;App=EntityFramework&';";
Update:
public ProcurementContext()
{
var s =
#"metadata=res://*/ProcurementModel.csdl|res://*/ProcurementModel.ssdl|
res://*/ProcurementModel.msl;provider=System.Data.SqlClient;
provider connection string=&';data source=JAMES-DESKTOP\SQLEXPRESS;initial catalog=MyDatabase;persist security info=True;user id=jd;password=P#ssw0rd;MultipleActiveResultSets=True;App=EntityFramework&';";
_connectionString = s;
}
Getting data:
public List<Procurement> ParcelListByUser(string userName)
{
using (var context = new ProcurementEntities(_connectionString))
{
return context.Procurements.Where(p => p.UserName == userName).ToList();
}
}
Constructor:
public ProcurementEntities(string connectionString)
: base(connectionString)
{
}
Error message:
Format of the initialization string does not conform to specification
starting at index 165.
Configuration:
The configuration of the Procurement
public class ProcurementConfiguration:DbConfiguration
{
public ProcurementConfiguration()
{
SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
SetDefaultConnectionFactory(new SqlConnectionFactory(ConnectionStrings.LocalConnectionString));
}
}

I think the issue is in your connection string. I've made the same thing and I have a function to create the connection string in an automatic way.
The code:
public static string GetConnectionString()
{
// Build the provider connection string with configurable settings
string cn = "server=" + mdlImpostazioni.p.dbServer;
cn += ";database=" + mdlImpostazioni.p.dbName;
cn += ";uid=" + mdlImpostazioni.p.dbUser;
cn += ";pwd=" + mdlImpostazioni.p.dbPassword + ";";
var providerSB = new SqlConnectionStringBuilder(cn);
var efConnection = new EntityConnectionStringBuilder();
// or the config file based connection without provider connection string
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 = #"res://*"; //-----> very important
return efConnection.ToString();
}
In this way, I pass the return value to my db context constructor, like in your code. My constructor is:
public partial class Entities : DbContext
{
public Entities(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
public void Close()
{
this.Dispose();
}
}
Try it and ask if you have some problem.

One way to change your connection string dynamically is to only change entity framework underlying connection's connection string. Something like this:
myDbContext.Database.Connection.ConnectionString = "Data source=JAMES-DESKTOP\SQLEXPRESS;initial catalog=MyDatabase;persist security info=True;user id=DynamicUser;password=DynamicPassword;MultipleActiveResultSets=True;App=EntityFrameworkForUser";
This way, your application does not have to hardcode tokens related to entity framework (i.e. metadata).

Related

C# login failed when connecting to SQL Server database for unit testing

I'm working on a project and when attempting to run a unit test to check progress, I get an error:
Initialization method UnitTestProject.UnitTest1.Init threw exception. System.Data.SqlClient.SqlException: Cannot open database "database" requested by the login. The login failed.
Login failed for user 'User\User1'
I've checked that User1 is owner in SQL Server and think I have the connection string right but I must be missing something obvious, please let me know :)
My repository class:
public class Repository
{
private string _connectionString;
public Repository()
{
_connectionString = configurationManager.ConnectionStrings["database"].ConnectionString;
}
public IEnumerable<Person> GetPeople()
{
var people = new List<Person>();
using (SqlConnection connection = new SqlConnection(_connectionString))
{
string commandText = "SELECT dbo.People.Id"
+ ", dbo.People.FirstName"
+ ", dbo.People.LastName"
+ ", dbo.People.Height"
+ ", dbo.People.Weight"
+ "FROM dbo.People";
SqlCommand command = new SqlCommand(commandText, connection);
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
people.Add(new Person()
{
Id = reader.GetInt32(0),
FirstName = reader.GetString(1),
LastName = reader.GetString(2),
Height = reader.GetDouble(3),
Weight = reader.GetDouble(4)
});
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return people;
}
}
My connection string in App.config:
add name="database"
connectionString="Data Source=localhost;Initial Catalog=database;Integrated Security=true"
My unit test:
public class UnitTest1
{
private Repository _repo;
[TestInitialize]
public void Init()
{
_repo = new Repository();
_repo.ResetDatabase();
}
[TestMethod]
public void GetPeople()
{
int count = _repo.GetPeople().Count();
Assert.IsTrue(count > 0);
}
}
Try adding the element to clear any connection strings that maybe previously defined:
<connectionStrings>
<clear />
<add name="DBConnection" connectionString="Data Source=xxxxxxxxxxx\xxxxxxxxx;Initial Catalog=xxxxx;Persist Security Info=True;User ID=xxxxxxxx;Password=xxxxxxxx"
providerName="System.Data.SqlClient" />
</connectionStrings>
It seems that creating a SQL server login with SQL authentication, i.e. user ID and password has allowed me to solve the login issue.
I then also had to update the connection string security from:
Integrated Security=true
to:
User id=admin;Password=password
Unfortunately I am now seeing this error when running the test:
Initialization method UnitTestProject.UnitTest1.Init threw exception.
System.Data.SqlClient.SqlException: A connection was successfully
established with the server, but then an error occurred during the
login process. (provider: Shared Memory Provider, error: 0 - No
process is on the other end of the pipe.) --->
System.ComponentModel.Win32Exception: No process is on the other end
of the pipe.
However there are existing solutions I'll be trying from:
No process is on the other end of the pipe (SQL Server 2012)

How to put string as connection string to app.config?

I want to put my connection string on a USB dongle lock and make my app to read connection string from the lock.
But I don't know how to pass the string to ado.net and the connection string placed on app.config.(I'm using ado.net)The following code is my connection string tag:
<connectionStrings><add name="Db_ReceptionEntities1" connectionString="metadata=res://*/Model.DBReception.csdl|res://*/Model.DBReception.ssdl|res://*/Model.DBReception.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=Db_Reception;user id=sa;password=******;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" /></connectionStrings>
How to put string as connection string to app.config?
You do not need to read from the dongle and put it into app.config. You can just read from the dongle and give the connection string to your context.
Your connection string looks like an EF database first connection string. The DbContext class has a constructor which accepts a connection string name or a full connection string. You can use that and pass the connection string to it.
Create your context like this:
public class StackContext : DbContext
{
public StackContext(string connection) : base(connection)
{
}
}
Then read the connection string from the dongle and pass it to your context like this:
// read from dongle
var connectionString = ...;
var ctx = new StackContext(connectionString);
this helped:
public Db_ReceptionEntities1(string x)
: base("name=Db_ReceptionEntities1")
{
Database.Connection.ConnectionString = x;
}

Set Entity Framework Connection String at Runtime in C#

I need to set my Entity Framework connection string at runtime. Right now, I have the following:
string connectionString = "metadata=res://*/DataModels.CustomerDataModel.csdl|res://*/DataModels.CustomerDataModel.ssdl|res://*/DataModels.CustomerDataModel.msl;provider=System.Data.SqlClient;provider connection string="data source=tcp:{serverName},{portNumber};initial catalog={databaseName};user id={username};multipleactiveresultsets=True;application name=EntityFramework"";
using (CustomerEntities entities = new CustomerEntities(connectionString))
{
CustomerEntity entity = new CustomerEntity();
// do more
entities.CustomerEntities.Add(entity);
entities.SaveChanges();
}
When I execute the code above (with the {parameter} values replaced), I get the following error:
Keyword not supported: 'data source'.
What am I doing wrong?
Change this.
string connectionString = "metadata=res://*/DataModels.CustomerDataModel.csdl|res://*/DataModels.CustomerDataModel.ssdl|res://*/DataModels.CustomerDataModel.msl;provider=System.Data.SqlClient;provider connection string="data source=tcp:{serverName},{portNumber};initial catalog={databaseName};user id={username};multipleactiveresultsets=True;application name=EntityFramework"";
To this (note how i escaped the " character as "" )
string connectionString = #"metadata=res://*/DataModels.CustomerDataModel.csdl|res://*/DataModels.CustomerDataModel.ssdl|res://*/DataModels.CustomerDataModel.msl;provider=System.Data.SqlClient;provider connection string= ""data source=tcp:{serverName},{portNumber};initial catalog={databaseName};user id={username};multipleactiveresultsets=True;application name=EntityFramework""";
I know this was asked 10 months ago, but I found an easier way to specify the connectionString:
If your config file has it as:
<connectionStrings>
<add name="CustomerDataModel" connectionString="metadata=res://*/EntityFramework.CustomerDataModel.csdl|res://*/EntityFramework.CustomerDataModel.ssdl|res://*/EntityFramework.CustomerDataModel.msl;provider=System.Data.SqlClient;provider connection string="data source=.\CustomerDataModel;initial catalog=CustomerDB;integrated security=True;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
You can specify it as -
public const string ConnectionString = #"name=CustomerDataModel";
..
CustomerDBContext context = new CustomerDBContext(ConnectionString );
No need to worry about quotes. Lot cleaner.
It is easier to use EntityConnectionStringBuilder and SqlConnectionStringBuilder to change parameters as you want.
set multiple connection strings in your web.config, and follow below:
public partial class MyDatabaseEntities
{
public MyDatabaseEntities(string connection)
: base(connection)
{
}
}
and then wherever you want to create instance of entities, pass connection string name in parameter:
MyDatabaseEntities entities = new MyDatabaseEntities("CONNECTION_STRING_NAME");
I hope this will help.
Thanks

Providing connection string to an EF 5.0 model

So I guess this is really simple, but for some reason I'm unable to find the answer. My problem is that I've before used EF 4.3.1 contexts that inherit from ObjectContext, and the autogeneration always created an overloaded constructor that accepted the connection string as a parameter.
Now that I'm trying to switch to EF 5.0, I have to use the DbContext version. But MyEntities that is inherited from DbContext, has only the parameterless constructor available. I guess I could add the overloaded constructor myself, and make it call base(connectionString), but doing manual changes to the auto-generated file just seems like a risky business at best.
So how can I create an instance of MyEntities that uses a connection string that I provide at runtime?
Have you tried using the connectionFactory?
This example is for SqLite, but it applies to all databases.
You can make a class similar to this one:
public class SqLiteConnectionFactory : IDbConnectionFactory
{
public System.Data.Common.DbConnection CreateConnection(string nameOrConnectionString)
{
var databaseDirectory = #"C:\\master.db";
var builder = new SQLiteConnectionStringBuilder
{
DataSource = databaseDirectory,
Version = 3
};
return new SQLiteConnection(builder.ToString());
}
}
and then use if by executing this statement before you access your context the first time:
Database.DefaultConnectionFactory = new ConnectionFactories.SqLiteConnectionFactory ();
Here is a function to build your connection string (for firebird here):
private static string ConnectionString(string dbFileName)
{
// Specify the provider name, server and database.
const string providerName = "FirebirdSql.Data.FirebirdClient";
const string metaData = "res://*/RcModel.csdl|res://*/RcModel.ssdl|res://*/RcModel.msl";
// Initialize the EntityConnectionStringBuilder.
EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
//Set the provider name.
entityBuilder.Provider = providerName;
FbConnectionStringBuilder sqlBuilder = new FbConnectionStringBuilder();
sqlBuilder.UserID = "sysdba";
sqlBuilder.Password = "masterkey";
sqlBuilder.DataSource = #"127.0.0.1";
sqlBuilder.Database = dbFileName;
sqlBuilder.Dialect = 3;
sqlBuilder.Charset = "UTF8";
sqlBuilder.ServerType = FbServerType.Default;
// Set the provider-specific connection string.
entityBuilder.ProviderConnectionString = sqlBuilder.ConnectionString;
entityBuilder.Metadata = metaData;
return entityBuilder.ToString();
}
Use it that way:
string cs = ConnectionString(#"C:\myDbFile.fbd");
EntityConnection conn = new EntityConnection(cs);
MyEntities db = new MyEntities(conn);
You can do it where you create MyEntities. Something like this:
MyEntities dataContext = new MyEntities();
dataContext.Database.Connection.ConnectionString = "<YOUR CONNECTION STRING>";
If your edmx is setup to look for a connection string in your config it will still do so when created but you can strip out the database provider connection string that embedded inside it. After doing that it would look something like this (if connecting to SQL):
<connectionStrings>
<add name="MyEntities" connectionString="metadata=res://*/MyEntities.csdl|res://*/MyEntities.ssdl|res://*/MyEntities.msl;provider=System.Data.SqlClient;provider connection string=;" providerName="System.Data.EntityClient" />
</connectionStrings>

How to change LINQ to SQL connection string dynamically at runtime and store in Project Settings?

I want to create a custom config screen so that I can modify the LINQ database connection at runtime. Apart from changing the app.config which would then require me to restart the software, is there anyway I can change the LINQ database connection string at runtime? And store this in the Project's Settings?
This is the code I use in my project. It's static so can be called anywhere. Change MyEntities and MyModel for the appropriate names for your project.
public static MyEntities NewContext()
{
var y = new System.Data.EntityClient.EntityConnectionStringBuilder();
y.Provider = "System.Data.SqlClient";
string conn = CodeToGetConnectionStringHere();
if(!conn.EndsWith(";")) conn += ";";
conn += "MultipleActiveResultSets=true";
y.ProviderConnectionString = conn;
y.Metadata = "res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl";
return new MyEntities(y.ConnectionString);
}
You can safely store your connection string in project settings; and build it using EntityConnectionStringBuilder class.
class ConnectionStringFactory
{
internal stati string BuildModelConnectionString(string connectionString)
{
var builder = new EntityConnectionStringBuilder
{
Provider = "System.Data.SqlClient",
Metadata = #"your metadata string",
ProviderConnectionString = connectionString
};
return builder.ConnectionString;
}
}
You can then use the method from above in your code like this:
var connectionString = ConnectionStringFactory.BuildModelConnectionString(Settings.ConnectionString);
using(var dataContext = new DataContext(connectionString))
{
// your logic here...
}

Categories

Resources