How to instantiate a DbContext in EF Core
Note
At the time of writing the use of EF Core with the Dependency injection framework wasn't as known as it is now. This answers gives answer to the question from a DI perspective, which at the time, helped out OP.
The other answer provides you a conventional way to instantiate the DbContext using the new
operator.
TL;DR, 3 options:
Option 1
Register the DbContext during application configuration:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<BlexzWebDb>(options =>
options.UseSqlServer(Configuration.GetConnectionString("BlexzWebConnection")));
}
and use the DI framework to retrieve it:
public class SomeController : Controller
{
private readonly BlexzWebDb _db;
//the framework handles this
public SomeController(BlexzWebDb db)
{
_db = db;
}
}
Option 2
If you are looking for a design-time IdentityDbContext
using IOptions<OperationalStoreOptions>
, see: Add migration for ApiAuthorizationDbContext from another project - EF Core
Option 3
Or use the new
operator and provide the details, see @Qamar Zaman's answer for details.
The long answer, and why DI is a treat
In EF Core it's common to pass some DbContextOptions to the constructor.
So in general, a constructor looks like this:
public BlexzWebDb(DbContextOptions<BlexzWebDb> options) : base(options)
As you can see there, there is no valid overload in the form of a parameter-less constructor:
Thus, this does not work:
using (var db = new BlexzWebDb())
Obviously, you can pass in an Option
object in the constructor but there is an alternative. So,
Instead
.Net Core has IoC implemented in it's roots. Okay, this means; you don't create a context, you ask the framework to give you one, based on some rules you defined before.
Example: somewhere you will register your dbcontext, (Startup.cs):
//typical configuration part of .net core
public void ConfigureServices(IServiceCollection services)
{
//some mvc
services.AddMvc();
//hey, options!
services.AddDbContextPool<BlexzWebDb>(options =>
options.UseSqlServer(Configuration.GetConnectionString("BlexzWebConnection")));
//...etc
Now the registering part is done, you can retrieve your context from the framework. E.g.: inversion of control through a constructor in your controller:
public class SomeController : Controller
{
private readonly BlexzWebDb _db;
//the framework handles this
public SomeController(BlexzWebDb db)
{
_db = db;
}
//etc.
why?
So, why not just provide the arguments and new
it?
There is nothing wrong with the use of new
- there are a lot of scenario's in which it works best.
But, Inversion Of Control is considered to be a good practice. When doing asp dotnet core
you're likely to use it quite often because most libraries provide extension methods to use it. If you are not familiar with it, and your research allow it; you should definitely give it a try.
Therefore, instead of providing "just a way to instantiate" the object, I'll try to get you onto this track - inline with the framework. It will save you some hassle afterwards. Besides, otherwise "use an activator's CreateInstance" would just be as valid as an answer ;-)
Some links:
- MSDN Fundamentals
- MSDN Dependency Injection
- Wikipedia Inversion Of Control
Instantiate a DbContext in IntegrationTests
The context still needs to get the connection string and configuration while your default constructor bypasses all of that.
First get rid of the default constructor in your Db context
public class MyContext : DbContext {
public MyContext(DbContextOptions<MyContext> options)
: base(options)
{ }
public DbSet<Employee> Employees { get; set; }
}
Next update the test to take advantage of the already provided configuration functionality
[Fact]
void TestMethod() {
//Arrange
var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
optionsBuilder.UseSqlServer("connection string here");
using (var context = new MyContext(optionsBuilder.Options)) {
var service = new MyService(context);
//Act
var result = service.GetAll();//Error here
//Assert
Assert.True(result.Count() > 0);
}
}
Reference Configuring a DbContext: Configuring DbContextOptions
How to create a class library that can use any Ef Core DbContext
You can use a where condition on Method.
public class TranslateManager : ITranslateManager
{
private readonly ContextDb _contextDb;
public TranslateManager(ContextDb contextDb)
{
_contextDb = contextDb;
}
public async Task CreateTranslationAsync<T>(long langId) where T : class, ITranslate
{
// ToDo
}
public async Task<ITranslate> GetBestTranslationAsync<T>(long langId) where T : class, ITranslate
{
var dbSet = _contextDb.GetDbSet<T>();
return await dbSet.Where(x => x.LangId == langId).FirstOrDefaultAsync();
}
}
public interface ITranslate
{
public long Id { get; set; }
public long ParentId { get; set; }
public long LangId { get; set; }
}
public partial class SectionTranslation : ITranslate
{
public long Id { get; set; }
public long ParentId { get; set; }
public long LangId { get; set; }
public string SectionName { get; set; }
}
public partial class TemplateTranslation : ITranslate
{
public long Id { get; set; }
public long ParentId { get; set; }
public long LangId { get; set; }
public string TemplateName { get; set; }
}
public interface ITranslateManager
{
Task<T> GetBestTranslationAsync<T>(long langId) where T : class, ITranslate;
Task CreateTranslationAsync<T>(long langId) where T : class, ITranslate;
}
How to instantiate DBContext in second thread?
You should be able use a using statement everywhere you need a unique instance and instantiate a new context that will be disposed when it is done.
using (var newContext = new TerminalDbContext(new DbContextOptionsBuilder<TerminalDbContext>()
{
// Define options
}))
{
DoSomething();
}
Create SQL Database From DBContext EF Core
The fastest way was running these commands:
Add-Migration InitialCreate
and Then:
Update-Database
Related Topics
What Really Happens in a Try { Return X; } Finally { X = Null; } Statement
Could Not Load File or Assembly ... the Parameter Is Incorrect
C# Naming Convention for Constants
Just What Is an Intptr Exactly
Setting Up Hook on Windows Messages
Regex: I Want This and That and That... in Any Order
How to Find the Extension of a File in C#
Best Practice to Make a Multi Language Application in C#/Winforms
Why Can't C# Interfaces Contain Fields
How to Get Current Page Url in MVC 3
Why Isn't Array a Generic Type
How to Get Duplicate Items from a List Using Linq
Should C# Methods That *Can* Be Static Be Static
Fast and Compact Object Serialization in .Net
Filter/Search Using Multiple Fields - ASP.NET MVC