Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework DbContext constructor with connection string

Can someone help me understand the following two approaches to pass a connection string to the DbContext?

Approach #1:

public EWebDBContextEMS() : base("mainConnectionString")
{
}

and approach #2:

public EWebDBContextEMS() : base("name=mainConnectionString")
{
}

This article states that name=... will get created by designer, but I tested with pure DbContext code, it works as well.

Is this an intented behaviour of the DbContext constructor? And in the documentation, it does not mention that name= is acceptable for connection string.

Many thanks

like image 960
Jonathon Avatar asked Jun 19 '14 13:06

Jonathon


2 Answers

The class DBContext Class remarks have the full explanation.
In short:

  • Your first example could result in a database called "mainConnectionString" being created.
  • name=xxxx looks in app.config for connectionStrings by name

Certain tools do put entries in App.config for you.
The online documentation you linked states exactly where the help is.

The online help says:

Constructs a new context instance using the given string as the name or connection string for the database to which a connection will be made. See the class remarks for how this is used to create a connection.

If you go to the class remarks you will find a full explanation....

///               The connection to the database (including the name of the database) can be specified in several ways.
///             If the parameterless DbContext constructor is called from a derived context, then the name of the derived context
///             is used to find a connection string in the app.config or web.config file.  If no connection string is found, then
///             the name is passed to the DefaultConnectionFactory registered on the <see cref="T:System.Data.Entity.Database"/> class.  The connection
///             factory then uses the context name as the database name in a default connection string.  (This default connection
///             string points to .\SQLEXPRESS on the local machine unless a different DefaultConnectionFactory is registered.)
///             Instead of using the derived context name, the connection/database name can also be specified explicitly by
///             passing the name to one of the DbContext constructors that takes a string.  The name can also be passed in
///             the form "name=myname", in which case the name must be found in the config file or an exception will be thrown.
///             Note that the connection found in the app.config or web.config file can be a normal database connection
///             string (not a special Entity Framework connection string) in which case the DbContext will use Code First.
 ///             However, if the connection found in the config file is a special Entity Framework connection string, then the
 ///             DbContext will use Database/Model First and the model specified in the connection string will be used.
 ///             An existing or explicitly created DbConnection can also be used instead of the database/connection name.
 ///             A <see cref="T:System.Data.Entity.DbModelBuilderVersionAttribute"/> can be applied to a class derived from DbContext to set the
 ///             version of conventions used by the context when it creates a model. If no attribute is applied then the
 ///             latest version of conventions will be used.
like image 145
phil soady Avatar answered Nov 07 '22 16:11

phil soady


The first approach allows you to create your own full connection string at runtime, rather than a named connection string in your app.config or web.config file.

Approach 2 uses a named connection string in your configuration files.

Using approach 1, and a partial class that handles the building of a connection string, you can build a connection string at runtime like:

The DbContext constructor accepts a connection string as a parameter. You may be better off building a connection string and passing that to the constructor like this:

I have used something like:

// the model name in the app.config connection string (any model name - Model1?)
private static string GetConnectionString(string model, settings)
{
    // Build the provider connection string with configurable settings
    var providerSB = new SqlConnectionStringBuilder
    {
        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();

}
like image 27
reckface Avatar answered Nov 07 '22 14:11

reckface