5
votes

I'm trying to get along with building web systems with ASP.NET vNext using MVC 6 and EF7. I'm looking at this tutorial: http://stephenwalther.com/archive/2015/01/17/asp-net-5-and-angularjs-part-4-using-entity-framework-7

On the page you'll see how to add a dbContext to a project and it's registered in the startup file like this:

// Register Entity Framework
services.AddEntityFramework(Configuration)
        .AddSqlServer()
        .AddDbContext<MoviesAppContext>();

And the context class looks like this:

public class MoviesAppContext:DbContext
{
    public DbSet<Movie> Movies { get; set; }
}

It all works good, but now I'm in need of adding an additional DbContext. Though I don't know how to register this additional context so that it will be used by EF and possible to use in my project.

Let's say I've created a new context like this:

public class MyNewSuper:DbContext
{
    public DbSet<Model1> Model1 { get; set; }
    public DbSet<Model2> Model2 { get; set; }
}

How do I go ahead to register it for use in my project then?

2
Did you try appending to the list of DbContexts? services.AddEntityFramework(Configuration) .AddSqlServer() .AddDbContext<MoviesAppContext>() .AddDbContext<MyNewSuper>(); - Michael
Can you not do all this with one context and three entities within that context? - Peter Smith
If your DBSets are in the same database, use the same DbContext. If they are in different databases, you will need to do much more if you want to get correct transactional behavior. - Alex
Alright. Well I was initially planning going with two databases. But I'll maybe leave that until later. Though I'm having some other issues right now preventing me from adding migration with the "k ef migration add" command. So I'll have to look into that first. - jimutt
@Alex - can you give a link or explain what you meant about "do much more to get transactional behavior" out of different databases - I've have tried really hard at this and found it impossible to get that behavior out of seperate databases - Scott Selby

2 Answers

14
votes

Important Note: The syntax for configuring the Entity Framework 7 services has changed since this post, which was accurate as of the last few beta rounds. The same idea should still apply to the new syntax though.

Here is what I've been doing:

services.AddEntityFramework().AddSqlServer()
                .AddDbContext<DataContextA>(options => options.UseSqlServer(Configuration.Get("StorageSettings:SQLConnectionString")))
                .AddDbContext<DataContextB>(options => options.UseSqlServer(Configuration.Get("StorageSettings:SQLConnectionString")));

where StorageSettings:SQLConnectionString is a connection string for a SQL Express database. Currently, I have both DataContextA and DataContextB sharing the same database, but you can keep them separate. If you want to keep using the Configuration method (which I wasn't aware of, pretty cool!) you could do something like this:

{
    "Data": {
        "DefaultConnectionA": { 
            "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=ContextADatabase;Trusted_Connection=True;MultipleActiveResultSets=true",
        "DefaultConnectionB": { 
            "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=ContextBDatabase;Trusted_Connection=True;MultipleActiveResultSets=true"
        }
    },
    "EntityFramework": {
        "DataContextA": {
            "ConnectionStringKey": "Data:DefaultConnectionA:ConnectionString"
        }            
        "DataContextB": {
            "ConnectionStringKey": "Data:DefaultConnectionB:ConnectionString"
        }
    }
}

with

services.AddEntityFramework(Configuration)
                .AddSqlServer()
                .AddDbContext<DataContextA>()
                .AddDbContext<DataContextB>();

Both DataContextA and DataContextB can be injected into your controller:

public class MyController: Controller {
    public MyController(DataContextA dataA, DataContextB dataB) {
        // Do stuff
    }
}
1
votes

First of all, in something like config.json you can add yur connection strings. Something like the following will work

  "Data": {
    "BlogData": { "ConnectionString": "Server=tcp:YourHostname.net,1433;Database=YourDatabaseName;User ID=YourDBUser@YourDomain;Password=YourPassword;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;" },
    "Identity": { "ConnectionString": "Server=tcp:YourHostname.net,1433;Database=YourDatabaseName;User ID=YourDBUser@YourDomain;Password=YourPassword;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;" }
  },

You then have two DBContexts. Let's say: YourApp.AppDBContext and YourApp.AppIdentityDBContext

You need to include these at the top of your CS file of course.

using YourApp.AppDBContext;
using YourApp.AppIdentityDBContext;

In startup.cs for example, in the startup method, your configuration builder will look like this:

    var builder = new ConfigurationBuilder()
        .AddJsonFile("config.json")
        .AddJsonFile($"config.{env.EnvironmentName}.json", optional: true);
    builder.AddEnvironmentVariables();
    Configuration = builder.Build();
}

In the ConfigureServices method you will add your DBContexts as follows:

    services.AddEntityFramework()
        .AddSqlServer()
        .AddDbContext<AppDbContext>(options =>
            options.UseSqlServer(Configuration["Data:BlogData:ConnectionString"]))
        .AddDbContext<AppIdentityDbContext>(options =>
            options.UseSqlServer(Configuration["Data:Identity:ConnectionString"]));

I hope this helps. Feel free to give me a shout if I can expand on this further.