106

How do I pass a connection string to entity framework's code-first DbContext? My database generation works correctly when both DbContext and the connection string in web.config is in the same project and named the same way. But now I need to move the DbContext to another project so I'm testing passing a connection string to it as follows:

Model & Context

public class Dinner
{
    public int DinnerId { get; set; }
    public string Title { get; set; }
}

public class NerdDinners : DbContext
{
    public NerdDinners(string connString)
        : base(connString)
    {
    }
    public DbSet<Dinner> Dinners { get; set; }
}

Action

    public ActionResult Index()
    {
        var db = new NerdDinners(ConfigurationManager.ConnectionStrings["NerdDinnerDb"].ConnectionString);

        var dinners = (from d in db.Dinners
                      select d).ToList();
        return View(dinners);
    }

Web.Config

<connectionStrings>
  <add name="NerdDinnerDb" connectionString="Data Source=|DataDirectory|NerdDinners.sdf" providerName="System.Data.SqlServerCe.4.0"/>    
</connectionStrings>

If I set a breakpoint in the action an analyze the db, the connection string is there, but it does not create or find the database or anything.

A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Shawn Mclean
  • 56,733
  • 95
  • 279
  • 406
  • Are you absolutely sure you're connecting to the correct server? The error is a typical SQL Server/Express exception. Doesn't sound like you're connection to an Sql CE database... and EF Code first will create the database if it doesn't exist... unless the path cannot be found perhaps... – Steven K. Jan 26 '11 at 14:57
  • So basically, OP's mistake was to send the entire connectionstring to the DbContaxt constructor, instead of just the name. As the documentations says: "DbContext(String) Constructs a new context instance using the given string as the name or connection string for the database" – Göran Roseen Jan 30 '20 at 12:29

11 Answers11

103

A little late to the game here, but another option is:

public class NerdDinners : DbContext
{
    public NerdDinners(string connString)
    {
        this.Database.Connection.ConnectionString = connString;
    }
    public DbSet<Dinner> Dinners { get; set; }
}
Bitfiddler
  • 3,942
  • 7
  • 36
  • 51
  • 2
    Hi! This was the only solution that got me somewhere. My problem is that I'd like to take the settings from my Azure configuration file instead of web.config. Still, this way does not work as the 'Provider' setting is missing (it's set as an attribute in the web.config). Any ideas? – user Oct 29 '13 at 08:43
  • 1
    Excellent answer! The only change made was to remove connString parameter, and then use the connection string saved in the application settings.... this.Database.Connection.ConnectionString = Properties.Settings.Default.ConnectionString – usefulBee Nov 17 '15 at 19:05
  • How can I pass both connString and DbCompiledModel object at the same time as parameter? – Behzad Ebrahimi Jun 02 '16 at 08:34
  • Nice. Just "this" is redundant, you can remove it. – tocqueville Jun 07 '16 at 17:19
  • 1
    if your class module includes `Manual changes to this file will be overwritten if the code is regenerated.` in the header, then one may want to implement this in a partial class as per [***Partial Classes and Methods (C# Programming Guide)***](https://msdn.microsoft.com/en-us/library/wa80x488.aspx) – woodvi Feb 16 '17 at 19:20
  • In my case it was `Database.GetDbConnection().ConnectionString` – iBobb Aug 25 '22 at 15:00
61

After reading the docs, I have to pass the name of the connection string instead:

var db = new NerdDinners("NerdDinnerDb");
Shawn Mclean
  • 56,733
  • 95
  • 279
  • 406
  • I put that in my constructor and made it a public constant in case it's needed for reference elsewhere. – Tony Wall Feb 19 '13 at 00:41
39

Thought I'd add this bit for people who come looking for "How to pass a connection string to a DbContext": You can construct a connection string for your underlying datastore and pass the entire connection string to the constructor of your type derived from DbContext.

(Re-using Code from @Lol Coder) Model & Context

public class Dinner
{
    public int DinnerId { get; set; }
    public string Title { get; set; }
}

public class NerdDinners : DbContext
{
    public NerdDinners(string connString)
        : base(connString)
    {
    }
    public DbSet<Dinner> Dinners { get; set; }
}

Then, say you construct a Sql Connection string using the SqlConnectioStringBuilder like so:

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(GetConnectionString());

Where the GetConnectionString method constructs the appropriate connection string and the SqlConnectionStringBuilder ensures the connection string is syntactically correct; you may then instantiate your db conetxt like so:

var myContext = new NerdDinners(builder.ToString());
Sudhanshu Mishra
  • 6,523
  • 2
  • 59
  • 76
  • 4
    To really hard code the connection string I did: `public TestAppContext() : base("Data Source=server.company.com;Initial Catalog=SomeDB;Integrated Security=True") { }` – Elijah W. Gagne Jun 09 '13 at 15:18
30

In your DbContext, create a default constructor for your DbContext and inherit the base like this:

    public myDbContext()
        : base("MyConnectionString")  // connectionstring name define in your web.config
    {
    }
Kinh Pham
  • 309
  • 3
  • 2
4

from here

 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
      optionsBuilder.UseSqlServer(ConfigurationManager.ConnectionStrings["BloggingDatabase"].ConnectionString);
    }

note you may need to add Microsoft.EntityFrameworkCore.SqlServer

Abdullah Tahan
  • 1,963
  • 17
  • 28
3

I have a little solution example for that problem.

MyDBContext.cs

 public MyDBContext(DBConnectionType ConnectionType) //: base("ConnMain")
  {
      if(ConnectionType==DBConnectionType.MainConnection)
       {
         this.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["ConnMain"].ConnectionString;
       }
      else if(ConnectionType==DBConnectionType.BackupConnection)
       {
         this.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["ConnBackup"].ConnectionString;
       }
  }

MyClass.cs

public enum DBConnectionType
 {
    MainConnection=0,
    BackupConnection=1
 }

frmMyForm.cs

 MyDBContext db = new MyDBContext(DBConnectionType.MainConnection);
                               //or
//MyDBContext db = new MyDBContext(DBConnectionType.BackupConnection);
Durgesh Pandey
  • 2,314
  • 4
  • 29
  • 43
2

When using an EF model, I have a connection string in each project that consumes the EF model. For example, I have an EF EDMX model in a separate class library. I have one connection string in my web (mvc) project so that it can access the EF db.

I also have another unit test project for testing the repositories. In order for the repositories to access the EF db, the test project's app.config file has the same connection string.

DB connections should be configured, not coded, IMO.

danludwig
  • 46,965
  • 25
  • 159
  • 237
2

If you are constructing the connection string within the app then you would use your command of connString. If you are using a connection string in the web config. Then you use the "name" of that string.

Techie
  • 44,706
  • 42
  • 157
  • 243
MKunstman
  • 41
  • 6
1

Check the syntax of your connection string in the web.config. It should be something like ConnectionString="Data Source=C:\DataDictionary\NerdDinner.sdf"

kmerkle
  • 58
  • 1
  • 2
  • 7
0

Can't see anything wrong with your code, I use SqlExpress and it works fine when I use a connection string in the constructor.

You have created an App_Data folder in your project, haven't you?

Lee Smith
  • 6,339
  • 6
  • 27
  • 34
0

For anyone who came here trying find out how to set connection string dinamicaly, and got trouble with the solutions above (like "Format of the initialization string does not conform to specification starting at index 0.") when setting up the connection string in the constructor. This is how to fix it:

public static string ConnectionString
{
    get {
        if (ConfigurationManager.AppSettings["DevelopmentEnvironment"] == "true")
            return ConfigurationManager.ConnectionStrings["LocalDb"].ConnectionString;
        else
            return ConfigurationManager.ConnectionStrings["ExternalDb"].ConnectionString;
    }
}

public ApplicationDbContext() : base(ConnectionString)
{
}