问题
I'm a bit confused by the (sparse) MSDN documentation on EF6 code-based configuration. I have a WPF application that needs to create an SQL connection based on command-line parameters and/or user input from a dialog. In older versions of EF I accomplished this by building the connection string and passing it to my derived DbContext every time.
It would be nice if I could avoid having to do that, since it also means having to pass the connection string to every view model that needs to use the context. It seems like the DbConfig in EF6 is on the path to accomplish that. Based on the docs, I have created a custom class that simply looks like this:
public class EfConfiguration: DbConfiguration
{
public EfConfiguration()
{
SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
SetDefaultConnectionFactory(new SqlConnectionFactory());
SetDatabaseInitializer<DataContext>(null);
}
}
Which, from my understanding, EF will pickup and do something with. But my question is, how do I then set the connection string once the application is running? And in doing so, does that mean I can now instantiate my DbContext with no parameters?
回答1:
In case anyone else runs across this problem, here's how I solved it:
DbContext has a constructor that accepts an existing connection. So my derived DbContext (called Entities in this case) has a constructor which looks like:
public Entities(IConnectionHelper connHelper)
:base(connHelper.GetConnection(), true)
{ }
The IConnectionHelper is an injected singleton that has properties for the server/db/uname/pw and upon changing them, builds an internal connection string using SqlConnectionStringBuilder. Since it's a singleton, the user can modify the properties from a dialog, for example, and they will still be accessible anywhere else. The GetConnection() method creates a connection from the factory:
SqlConnectionFactory connFactory = new SqlConnectionFactory(_connectionString);
return connFactory.CreateConnection(_connectionSettings.Database);
Where _connectionString is just the string I built and _connectionSettings is just a POCO that holds the various connection parameters.
Then to achieve the goal of having a parameterless construction of the DbContext, I made a simple factory which gets the IConnectionHelper constructor-injected as a dependency:
public EntitiesFactory(IConnectionHelper connHelper)
{
_connHelper = connHelper;
}
public Entities Create()
{
return new Entities(_connHelper);
}
I inject this factory into any classes that need it, and then it's a simple matter of:
using (var db = _entitiesFactory.Create())
{ ... }
You could also make the factory method static and not worry about injecting, but I did it this way to facilitate testing.
回答2:
Just wanted to post here for my own future googling benefit that the DBContext base class also has a contructor that accepts a connection string, so you can go into your context text template and use that constructor :)
Easy Peasy
来源:https://stackoverflow.com/questions/21891633/how-to-set-connection-in-entity-framework-6-using-code-based-configuration