1

EF code first migrations require me to put a default constructor on my DbContext class, this requires me to know the exact connection string - however, I don't know the connection string yet.

My context and the entities reside in a MyProject.Data assembly with no information about the actual database whatsoever. The connection string is in the MyProject.Executable's app.config file. Still I want to put all the migrations into the MyProject.Data project, because that is where they belong.

Is there any way to do EF migrations without having a default CTOR, etc.?

D.R.
  • 20,268
  • 21
  • 102
  • 205
  • `Update-Database` has a `-StartupProjectName` parameter: http://coding.abel.nu/2012/03/ef-migrations-command-reference/. Use the default base constructor, and point at the project that contains the connectio string using that? – millimoose Jun 04 '14 at 07:32
  • Unfortunatelys this is still requiring me to write an empty default ctor, however, this is by far the best solution up to now. If you convert your comment into an answer, I'll upvote it! – D.R. Jun 04 '14 at 07:49
  • you may find this useful http://stackoverflow.com/a/20112084/1347784 – phil soady Jun 04 '14 at 07:54

2 Answers2

0

If the connectionstring is in the app.config/Web.config of your main project (the one you will be building), you can use ConfigurationManager.ConnectionStrings to retrieve them.

If you are wondering how it will work if it's in a different project: This will only be executed at runtime. At runtime, your projects have been compiled into one big application, and everything listens to the same app.config/Web.config file (the one that was in your startup project when you built it).

From the link:

var connectionString =     
        ConfigurationManager.ConnectionStrings["WingtipToys"].ConnectionString;

using (var connection = new SqlConnection(connectionString))
 {
   //...
 }

The same applies for any constructor where you need to know the connectionstring, like your DBContext.

According to this SO answer, you only need to pass the name of your connectionstring, so that means you don't even need to use ConfigurationManager.

From the linked answer:

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

var db = new NerdDinners("NerdDinnerDb");
Community
  • 1
  • 1
Flater
  • 12,908
  • 4
  • 39
  • 62
  • "At runtime, your projects have been compiled into one big application" – I don't like to spread FUD, but EF migrations *might* work another way. I.e. link to your model DLL directly, instead of the build output of your main project. – millimoose Jun 04 '14 at 07:22
  • Maybe it was a bad phrasing. What I meant is that the boundaries of different project *kind of fade away*. Not for access modifiers like `internal`, but more in terms of the .config file that is used. However, and you do make a good point, I seem to rememeber that you indeed also need to put the connectionstring inside your migrations project, because a migrations has not much to do with the application's actual runtime. But that doesn't affect how the *constructor of the DBContext* should be used, as that piece of code is part of the 'normal' runtime. IIRC – Flater Jun 04 '14 at 07:27
  • That's an even worse phrasing. They don't just "fade away", the boundaries are set using some very clear rules. (Like, say, a search path that looks for `.config` files.) And the OP's problem remains. EF Migrations will call `new NerdDinners()`, and that has to call a base constructor, which cannot read the `.config`, but somehow needs a connection string. – millimoose Jun 04 '14 at 07:29
  • `you indeed also need to put the connectionstring inside your migrations project`. When you do a migration, that migration project is the startup project. Therefore, anything I mentioned before does not apply for this because I specifically said it only works when the startup project has the connectionstring in its config file. Use a different startup project, you'll need to make sure the string is in that file as well. That still doesn't change the fact that you have to use the *name of the connectionstring that is used in the startup project's config file*, which is my original statement. – Flater Jun 04 '14 at 07:34
  • 1
    So you answer to the OP's question, which is essentially "how to make a migration use a connection string in a different `.config` file", is a very tl;dr "don't"? – millimoose Jun 06 '14 at 12:55
  • Read the first sentence of my answer, which is still unchanged. Keep in mind that for executing a migration, your migration project is the startup project, which I've stated before. I've never had a migration work if I set a *different* project as the startup project. – Flater Jun 06 '14 at 14:17
0

You can refer to the name of connection string placed in your default start up project. This is why parameter of DbContext constructor is nameOrConnectionString.

public class MyContext : DbContext
{
    public MyContext()
         : base("Name=NameOfConnectionString")
    {
    }
}
MacGyver
  • 2,983
  • 1
  • 17
  • 14
  • Within my MyProject.Data assembly (containing the context), I don't know the name of the connection string in the executable project. I guess I could make it a global constant, however, I don't want to force that if it is not 100% necessary. – D.R. Jun 04 '14 at 07:50
  • In this situation, I am afraid there is no other option other than creating global constant or getting name of connection string from _.resx_ file. – MacGyver Jun 04 '14 at 08:30