Reputation: 3982
I am relatively new to EF7 and have heard that Dependency Injection of DbContexts into the Controller constructor is a good way to go about getting the DbContext for use within given Action methods. However, there are many situations where Dependency Injection is impossible (for example, accessing the Db in ordinary classes), and the using(VectorDbContext dbContext...)
pattern must be used.
I have run into an issue where adding data to a DbContext created with the using
pattern cannot be accessed by a context that was dependency injected. The DbContext is a simple InMemory database used for testing - it doesn't connect to anything.
Here is the code that adds entities to the DbContext, for testing I am calling this in Startup.cs:
using (ExampleDbContext dbContext= new ExampleDbContext()) {
dbContext.Things.Add(
new Thing() {
Stuff= "something"
});
dbContext.SaveChanges();
}
Here is the access code within the Controller:
public class ExampleController : Controller {
public ExampleController(ExampleDbContext exampleDbContext) {
this.ExampleDbContext= exampleDbContext;
}
public ExampleDbContext ExampleDbContext { get; set; }
public async Task<IActionResult> ExampleAction() {
// new DbContext:
using(ExampleDbContext dbContext = new ExampleDbContext ()) {
var List1 = (await dbContext.Things
.AsNoTracking()
.ToListAsync());
}
// Injected DbContext:
var List2 = (await this.ExampleDbContext.Things
.AsNoTracking()
.ToListAsync());
}
}
When stepping through, List1 has the expected one item in it, but List2 is always empty!
What am I doing wrong? It appears the DbContexts aren't in sync somehow, how does Dependency Injection create the DbContext/where does it come from?
EDIT: I just did some additional testing and have confirmed that any entities added within the DbContext created with new
are only visible in new
, and the entities added within the Injected DbContext are only visible within the Injected DbContext, leading me to believe they are connecting to different backing databases, but I cannot confirm.
Upvotes: 2
Views: 1353
Reputation: 5899
I might be wrong, but my assumption is that when you create a new instance of DbContext
in code, you are using the parameterless constructor that sets underlying connection string to some default value. However, DI-injected DbContext
could be resolved using another constructor with different connection string passed in explicitly.
That's an example of Unity config that explicitly specifies constructor parameter:
<register type="DbContext, [assembly-name]" mapTo="DbContext, [assembly-name]">
<constructor>
<param name="nameOrConnectionString" value="Test"/>
</constructor>
</register>
So I would check a configuration of your container.
Upvotes: 2