How to take advantage of EntityFramework.Core in .net Core 2.2 console applications
This is related my prior article on dependency injection in .net core 2.2 console apps, configuration, and logging. I am assuming once again that you’ve read that before coming here. Otherwise this will make no sense.
In previous articles we established dependency injection and enabled use of configuration and logging. Now its time to put Entity Framework Core into the mix.
I am going to assume you have been following along and have built the application so far. If you have not, go back and do so, otherwise reading this will be a waste of time.
As always, we need to add a couple new NuGet packages to the mix. Also as always, if you don’t know how to do this, go away. Leave. Now.
Add the following packages to the ones we already have:
- Microsoft.EntityFrameworkCore
- Microsoft.EntityFrameworkCore.SqlServer
Now, just like any other time we connect to SQL Server, we need to specify our connection string. Add the following section to you appSettings.json file:
"ConnectionStrings": { "Storage": "Server=...;" }Obviously you will need to fill in the correct connection string.
Now we need to have some things to use when connecting to the database. We will need two things:
- Our entity
- Our database context
Entities
We need at least one entity, so we will add a very simple one:
public class SampleEntity
{
public int Id {get; set;}
public string Name {get; set;}
}Database context
Our database context will look a lot like standard Entity Framework Context, but we will need to make a couple tweaks:
So, first, lets create our dbContext class
public class SampleDbContext : DbContext
{
public DbQuery<SampleEntity> SampleEntities {get; set;}
} Here is where things get a little different. Instead of passing in a connection string, or just using a default, we will pass in an instance of DbContextOptions, which of course, we will pass in via dependency injection. We will tell the contextOptions object what connection string to use.
When we pass in the DbContextOptions instance, we need to pass this along to the base class. So our constructor might look like:
private readonly IConfiguration _configuration;public SampleDbContext(IConfiguration configuration,
ILogger<SampleDbContext> logger, DbContextOptions
dbContextOptions):base(dbContextOptions)
{
_configuration = configuration;
}As mentioned, we pass the dbContextOptions object along to the base class (DbContext) where it is kind enough to set up our connection for us.
Next, we open our favorite Program.cs file and update our ConfigureServices method to properly inject our database connection string. It will look like:
private static IServiceCollection ConfigureServices()
{
IServiceCollection services = new ServiceCollection();
var config = LoadConfiguration();
services.AddLogging(logging =>{
logging.AddConfiguration(config.GetSection("Logging"));
logging.AddConsole();
}).Configure<LoggerFilterOptions>(options=>options.MinLevel =
LogLevel.Information); services.AddSingleton(config); services.AddTransient<ITestService, TestService>(); // Set up our database by adding the dbcontext to our services
// collection. Then set up our options object for injection services.AddDbContext<SampleDbContext>
(opts=>opts.UseSqlServer(config.GetConnectionString("Storage"))); services.AddTransient<ConsoleApplication>();
return services;
}As noted, we add our context into the collection of DbContexts and we configure its options with a sql server connection string.
Now, finally, we are ready to use it! So, we will inject our database context into our service (probably want to use an actual repository for this, but this is just an example).
So we update our service constructor to look like:
public class TestService : ITestService
{
private readonly ILogger<TestService> _logger;
private readonly SampleDbContext _sampleDbContext; public TestService(SampleDbContext dbContext,
ILogger<TestService> logger)
{
_sampleDbContext = dbContext;
_logger = logger;
} public void DoSomethingUseful()
{
var result = from s in _sampleDbContext.SampleEntities
where s.Name = "...."
select s;} }
Boom! there you go! Database access in a dependency injected, logging, configurable console application using .Net Core 2.2.
Just a couple last points. If you are concerned about injecting the dbContext and not using the dispose pattern to get rid of it, don’t be. The call to AddDbContext in our ConfigureServices method will release it when its out of scope. So yay!
Anyway, that’s about all I have to say about console applications. Have fun and don’t do anything too crazy!
