3

I'm currently working on an ASP.NET MVC 4 project that is using Entity Framework 4.3 with a CodeFirst approach using simple POCO classes. Also, I'm using SQL Server Express as the development database.

After building my classes and setting the connection string, I ran my project and it generated a SQL Server Express database for me with no problems.

The problem though, is that I am trying to deploy to AppHarbor and I'm having an issue with the connection string. AppHarbor requires that you install SQL Server as an 'Add-On' and configure the connection string to have an alias that will inject their Sequilizer connection string into the project that you push from GitHub.

Here is their documentation on how this works: http://support.appharbor.com/kb/add-ons/using-sequelizer

I believe I have all of this setup correctly, but there seems to be a problem with how my app is reading the connection string.

Here is the development connection string that I am using on my local machine:

<connectionStrings>
    <add name="DefaultConnection" 
         connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=aspnet-FranchiseManager-201275154247;Integrated Security=True" 
         providerName="System.Data.SqlClient" />
</connectionStrings>

Here is what the AppHarbor Sequilizer connection string looks like:

<connectionStrings>    
    <add
      name="DefaultConnection"
      connectionString="Server=0691298f-d461-40cc-86d6-a089016ba88d.sqlserver.sequelizer.com;Database=<removed hash value>;User ID=<removed hash value>;Password=<removed hash value>;"
      providerName="System.Data.SqlClient"
    />
  </connectionStrings>

The first connection - generated locally by my EF - works just fine. The second - created by Sequilizer - is not being read by my application.

However - I can connect to the Sequilizer database through SQL Server Management Studio. So it must be my app right?

In order to trouble shoot my deployment to AppHarbor, I hard-coded their connection string into my app instead of the one auto-generated by EF and tested on my local machine.

Here's what I did:

  1. Replaced the connection string in Web.config with the one AppHarbor provided,
  2. Cleaned the solution,
  3. Rebuilt the solution

But when I ran the application, it is still utilizing the original database generated by EF - which must mean that it is still reading the old connection string.

It seems like changing the connection string is not enough. What else in my application should I change in order to replace the connection string?

Any advice is appreciated - thanks!


EDIT


Here is my DbContext class:

public class FranchiseManagerContext : DbContext
    {
        public DbSet<FranchiseSet> FranchiseSets { get; set; }
        public DbSet<Franchise> Franchises { get; set; }

    }

This works as-is with the connection string named "DefaultConnection".

How does EF know to match the DbContext with the connection string in this scenario, but it cannot do it if you change the name of the string?

UPDATE

I think I know what it is now from this SO answer: What is the point of "Initial Catalog" in a SQL Server connection string?

It looks like the Initial Catalog attribute is specifying the particular database to be used when Entity Framework first kicked in.

Community
  • 1
  • 1
PhillipKregg
  • 9,358
  • 8
  • 49
  • 63

2 Answers2

13

You have to specify the name of the connectionstring you want your DbContext to load. It has no way to magically guess that you want it to use the one called DefaultConnection. There's a heuristic that says that if no name is specified, it'll look for for a connectionstring with name set to the name of the class that inherits from DbContext. Ie. if you have:

MyAwesomeDatebase : DbContext

... then Entity Framework will work out of the box with this:

<add name="MyAwesomeDatebase" connectionString="blah" providerName="System.Data.SqlClient" />

... but if you have:

<add name="DefaultConnection" connectionString="blah" providerName="System.Data.SqlClient" />

... then it won't work because Entity Framework has no way of knowing that MyAwesomeDatebase goes with DefaultConnection.

To make that work, do this:

public class MyAwesomeDatebase : DbContext
{
    public MyAwesomeDatebase() : base("DefaultConnection")
}

... and you're golden.

friism
  • 19,068
  • 5
  • 80
  • 116
  • Ok, this is good information thanks! One question though - why is it that when I created the first instance of my database with EF (my development environment), I didn't need to do this? I only needed to provide the connection string - no other configuration. I'll add my context class in my original post under EDIT as an example. – PhillipKregg Jul 20 '12 at 02:50
  • Nevermind - I just figured out that in the original connection string, there is an 'Initial Catalog' attribute that is specifying the database to be used. Sorry for all the questions - I'm learning this stuff as I go so there's a lot to figure out. Thanks again! – PhillipKregg Jul 20 '12 at 03:33
0

Ok, I think I've finally got this working.

I can't find this anywhere in the AppHarbor documentation (perhaps it is something specific to .net mvc?), but the connection string must have the same name as my DbContext class.

I found some hints on this by looking at some other questions on SO.

For anyone else that may run into the same issue:

  1. be sure the name attribute of the ConnectionString in Web.config is the same name as your DbContext Class
  2. Commit and push the project to your repo
  3. Make sure the Alias name on AppHarbor is the same name as your connection string
  4. Deploy the new build on app harbor after step 3 (this is necessary to pick up the new connection string name)

After doing that my app picked up the Sequilizer database and it's now working fine.

PhillipKregg
  • 9,358
  • 8
  • 49
  • 63
  • It's not an AppHarbor-specific issue. If you don't specify a connectionstring name Entity Framework Code First will look for one with the same name as the class that inherits `DbContext`. – friism Jul 19 '12 at 23:35
  • As you see in my code snippet above, I did specify a connection string name. But the Sequilizer string would only work if the name matched the DbContext - regardless of whether or not I had another name. Any ideas on what the issue could be with that? If there is a better solution I'm open to different ways of approaching it. – PhillipKregg Jul 20 '12 at 00:34