Comments (18)
@funzeye this is all changing in the upcoming RC2 and IdentityDbContext will have a constructor that allows you to pass in all this stuff.
from entityframework.docs.
Following code works perfectly for me,
// Requires separate DI Service provider to isolate db instance as InMemory database is also shared within
// the class scope since the App Service Factory is configured to per scope instance for dbcontext
var internalServiceProviderForDbContext = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
var options = new DbContextOptionsBuilder()
.UseInternalServiceProvider(internalServiceProviderForDbContext)
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
.Options;
As pointed out by @ajcvickers , internal service provider is not required. specifying the inMemoryRoot in optionbuilder is the best way to do it.
from entityframework.docs.
Should also cover this point that was mentioned in #105
Keep DbContext's isolated; don't re-use the same context to seed the database and then query.
from entityframework.docs.
I'm trying to write a test that uses two DbContext's, sharing the same in-memory DB. The idea is to create the entities using the first context, and pass a clean context to the code that I'm testing. That way I can validate that I'm loading navigation properties correctly, etc, in my EF7 code. The best I could find was to register my DbContext as a transient:
public class TestClass
{
private readonly ServiceCollection _serviceCollection;
private readonly DbContextOptions<MyDbContext> _options;
public TestClass()
{
var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
optionsBuilder.UseInMemoryDatabase();
_options = optionsBuilder.Options;
var _serviceCollection = new ServiceCollection();
_serviceCollection
.AddEntityFramework()
.AddInMemoryDatabase();
_serviceCollection.AddTransient<MyDbContext>(provider => new MyDbContext(provider, _options));
}
[Fact]
public Test1()
{
IServiceProvider provider = _serviceCollection.BuildServiceProvider();
using (var context = provider.GetService<MyDbContext>())
{
context.Add(new Thing { Id = 1 });
context.SaveChanges();
}
using (var context = provider.GetService<ApplicationDbContext>())
{
// test with a new context but same DB
}
}
}
It seems to work, but is there a better way to achieve this?
from entityframework.docs.
@MikeWasson it's a bit of a "level up" on DI skills... but you can create scopes within a service provider to get new instances of scoped services... but the non-scoped services (such as the InMemory store) are shared between all scopes on the provider.
This actually emulates nicely what happens in ASP.NET - where a new scope is created for each request. So Test1()
now approximates some data being inserted on one request and then some other logic happening on a second request that accesses the same database.
public class TestClass
{
private readonly ServiceCollection _serviceCollection;
public TestClass()
{
_serviceCollection = new ServiceCollection();
_serviceCollection
.AddEntityFramework()
.AddInMemoryDatabase()
.AddDbContext<SampleContext>(c => c.UseInMemoryDatabase());
}
[Fact]
public Test1()
{
IServiceProvider provider = _serviceCollection.BuildServiceProvider();
using (var scope = provider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = scope.ServiceProvider.GetService<MyDbContext>())
context.Add(new Thing { Id = 1 });
context.SaveChanges();
}
using (var scope = provider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = scope.ServiceProvider.GetService<MyDbContext>())
// test with a new context but same DB
}
}
}
from entityframework.docs.
Page is now available at http://docs.efproject.net/en/latest/miscellaneous/testing.html
@MikeWasson I came up with some patterns to make things a little simpler (though we still have plenty of room for improvement - mostly implementing dotnet/efcore#3253) so you should take a look at the final article.
from entityframework.docs.
Awesome Rowan! :) That was exactly what I needed to understand how to scope my contexts :)
from entityframework.docs.
@rowanmiller Thanks Rowan. Your doc was helpful !
from entityframework.docs.
inheriting from IdentityDbContext throws a bit of spanner in the works with this: (http://docs.efproject.net/en/latest/miscellaneous/testing.html) - it doesnt contain a constructor that takes two arguments
from entityframework.docs.
cool,
great work guys. EF FTW.
from entityframework.docs.
@rowanmiller Hi. I reported this a while ago and since then the named dbcontext can be passed in but -- I find that the context is still shared.
I probably use a weird edge-case, but I am performing a bunch of integration tests in xunit (which work better than I could have ever hoped, with the exception of this problem) that spins up a TestServer with UseInMemoryDatabase for each test class.
The problem is, even with separate test servers, with separate dbcontexts, the underlying in memory database was still shared (each was created with a new Guid for a name)
I also get a "A second operation on this context....." type error that I'll never see in actual production all the time due to apparent context sharing.
from entityframework.docs.
@mgallig Please file a new issue on https://github.com/aspnet/EntityFramework including a full code listing or project that will let us reproduce what you are seeing.
from entityframework.docs.
where is ServiceCollection class
from entityframework.docs.
@babu12f https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.servicecollection?view=aspnetcore-2.1
from entityframework.docs.
Following code works perfectly for me,
// Requires separate DI Service provider to isolate db instance as InMemory database is also shared within
// the class scope since the App Service Factory is configured to per scope instance for dbcontext
var internalServiceProviderForDbContext = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
var options = new DbContextOptionsBuilder()
.UseInternalServiceProvider(internalServiceProviderForDbContext)
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
.Options;
from entityframework.docs.
@logamanig It's generally best to avoid calling UseInternalServiceProvider
if you don't really need to.
from entityframework.docs.
@logamanig It's generally best to avoid calling
UseInternalServiceProvider
if you don't really need to.
without calling UseInternalServiceProvider, not able to isolate the InMemoryDatabase instance between test cases. Just a unique database name is not enough to isolate.
from entityframework.docs.
See dotnet/efcore#3253 (comment)
from entityframework.docs.
Related Issues (20)
- Document ListValueComparer breaking change
- Document MsBuild integration
- Documentation improvement about data-seeding
- Concerning DbContext disposal HOT 1
- missing defaults information HOT 1
- I cant make use of the Entity.FrameworkCore HOT 1
- Missing doc about Primitive Collections HOT 1
- Doc does not address the most common use-case, when DbContext is injected
- Entity Framework Core 9 HOT 2
- AddRange & Internal Snapshot Method Missing Info
- Primitive Collection Must Implement IList
- Please provide some code samples how to use it in reality. HOT 1
- include
- NoTracking and NoTrackingWithIdentityResolution have the same description. HOT 1
- Numeric rowversions doesn't need a HasConversion call HOT 1
- Document materialization interceptors are singleton HOT 1
- Migrations HOT 1
- Missing information on setting clustering with attributes
- document results for "undefined behavior" queries, e.g. Min/Max on an empty collection, StartsWith(null), etc
- EntityTypeAttributeConventionBase disappeared HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from entityframework.docs.