0

I created a web starter application with VS 2015 ctp, and I would like to add an in-memory store to do some test, but when I try to read the data, I get this message

The data stores 'SqlServerDataStore' 'InMemoryDataStore' are available. A context can only be configured to use a single data store. Configure a data store by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services.

How can I do to create a second datastore? Now I have this row in the ConfigureService method

AddEntityFramework(Configuration)
  .AddSqlServer()
  .AddDbContext<ApplicationDbContext>()
  .AddInMemoryStore()
  .AddDbContext<WorkModel>( options => { options.UseInMemoryStore(persist: true); });

Edit: Looks like the scenario is not clear. I have the identy sql server dbcontext, and I want to add a second dbcontext, totally separated, that I want to run in memory. I'm looking how configure two different dbcontext, in this case using two different datastores.

The first one is the Identity ApplicationDbContext, and another is something like this:

public class WorkModel : DbContext
{

    public DbSet<Cliente> Clienti { get; set; }
    public DbSet<Commessa> Commesse { get; set; }

    protected override void OnModelCreating(ModelBuilder builder) {
        builder.Entity<Cliente>().Key(cli => cli.ClienteId);
        builder.Entity<Commessa>().Key(cli => cli.CommessaId);
    }
}

Or whatever custom dbcontext do you like

Luca Morelli
  • 2,530
  • 3
  • 28
  • 45
  • 1
    Which part of *A context can only be configured **to use a single** data store* don't you understand? You **cannot** do this - you can use **either** SQL Server, **OR** in-memory - one OR the other - but not BOTH at the same time – marc_s Mar 14 '15 at 22:13
  • I want to configure a second data store – Luca Morelli Mar 15 '15 at 06:38
  • 1
    Well, as the error message clearly : this is **not possible**. – marc_s Mar 15 '15 at 07:35
  • can you post the code for these 2 context classes? right now, everything you have presented suggests you have one context class and you tried to add another database; nothing here suggests you created a second class that inherits from DbContext.... – Claies Mar 16 '15 at 20:38

4 Answers4

2

It's possible use one DbContext type with multiple data stores. It won't however play well with your calls to .AddDbContext(). Here is an example of how to do it taking .ConfigureServices() entirely out of the picture.

class MyContext : DbContext
{
    bool _useInMemory;

    public MyContext(bool useInMemory)
    {
        _useInMemory = useInMemory;
    }

    protected override void OnConfiguring(DbContextOptions options)
    {
        if (_useInMemory)
        {
            options.UseInMemoryStore(persist: true);
        }
        else
        {
            options.UseSqlServer();
        }
    }
}

You can then instantiate your context specifying which provider to use.

var inMemoryContext = new MyContext(useInMemory: true);
var sqlServerContext = new MyContext(useInMemory: false);
gius
  • 9,289
  • 3
  • 33
  • 62
bricelam
  • 28,825
  • 9
  • 92
  • 117
  • thank, but honestly I'm looking for a simpler solution: two db context, one with a sql server datastore and another with in memory data store. – Luca Morelli Mar 16 '15 at 20:17
  • @LucaMorelli I'm not sure how much simpler you can get than this solution. Using two different contexts would make your testing moot. – JNYRanger Mar 16 '15 at 20:37
  • the point is not to have the same dbContext running sometimes with sql server and sometimes in memory, but to have two differents db context running using different datastores – Luca Morelli Mar 16 '15 at 21:02
  • 1
    Large DB contexts can have a lot of initialization logic - so always creating it when you need it becomes cumbersome. Especially if every warning or info message is output to the console every time you create a new one. And EFCore now supports connection pooling so you lose out on that. [I have essentially the same question but i need a configurable timeout] – Simon_Weaver Mar 22 '18 at 22:37
1

You probably need to do something like this instead...

// Add first DbContext here
AddEntityFramework(Configuration)
  .AddSqlServer()
  .AddDbContext<ApplicationDbContext>();

// Add second DbContext here
AddEntityFramework(Configuration)
 .AddInMemoryStore()
 .AddDbContext<WorkModel>(options => { options.UseInMemoryStore(persist: true); });

In my case, when I needed to create two SQL Contexts, I had to do this...

AddEntityFramework(Configuration)
  .AddSqlServer()
  .AddDbContext<ApplicationDbContext>()
  .AddDbContext<AnotherDbContext>();
cwiederspan
  • 95
  • 1
  • 7
0

In my case, I'm using Entity Framework Core 1.0.1 with ASP.NET Core 1.0.1 and I want to run the same project on Windows and OS X but with different databases. So this is working for me:

Added some logic in Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("WindowsConnection")));
    }
    else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlite(Configuration.GetConnectionString("OSXConnection")));
    }
}

Then defined the two different connection strings in appsettings.json:

"ConnectionStrings":
{
  "WindowsConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-{dbname}-{dbguid};Trusted_Connection=True;MultipleActiveResultSets=true",
  "OSXConnection": "Data Source=\/Users\/{username}\/Documents\/{projectname}\/bin\/debug\/netcoreapp1.0\/{dbname}.db"
}

And added this logic to ApplicationDbContext.cs:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
    {
        optionsBuilder.UseSqlite("Filename=./{dbname}.db");
    }
}
Ricky
  • 10,044
  • 3
  • 26
  • 31
crgolden
  • 4,332
  • 1
  • 22
  • 40
0

If you're dbcontext has

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
        #warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
        optionsBuilder.UseSqlServer(<connection string>);
}

then you can avoid the double configuration by adding a guard

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if(!optionsBuilder.IsConfigured){
        #warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
        optionsBuilder.UseSqlServer(<connection string>);
    }
}

and then have a class that extends your DBContext which uses the inmemory provider, and you instantiate explicitly for your tests. Then you can pass in to the target classes, and avoid the double provider issue.

Austin_Anderson
  • 900
  • 6
  • 16