Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.Net Core 2.1 Web and Console DbContexts

Im not known for my clarity when asking questions, so forgive me, also i have no formal training for any of this but im stumped.

I am mid upgrade from .Net 4.7.1 to .Net Core 2.1, my solution consists of 2 parts, an IIS Web Application for MVC, and a Console Application, the IIS App displays data, and the console application does all the actual processing.

Before i started this port for my console app when i needed stuff from the database i would simply

using (var db = new ApplicationDbContext())
{
    SomethingModel model = db.X.First(x => x.Whatever == whatever);
}

And just like that i have the data i want from the database, butttt do you think i can do that with Core 2.1 can i hell.

I got all the code ported all the refrences resolved and so far as i can tell its ready to run. Except i cant call data from the database and im stumped, google just shows code first and ef stuff, or i dont know what im really asking.

So if anyone can help its much appreciated

-- Update 1---

The error is An Object refrence is required for the non-static field, metho or property Program._db

The DbModel is defined in Data/ApplicationDbContext.cs for the IIS App and is as follows

public ApplicationDbContext(DbContextOptions<ApplicationDbContext>
options)
            : base(options)
         {
         }

-- Program.cs for Console App

 class Program
    {
        private ApplicationDbContext _db { get; }
        public Program(ApplicationDbContext context)
        {
            _db = context;
        }
        static void Main(string[] args)
        {
            new ExecutionEngine(_db).Run();
        }
    }
like image 574
Mark Avatar asked Jun 06 '18 12:06

Mark


People also ask

Can I use Entity Framework 6 in .NET core?

To use Entity Framework 6, your project has to compile against . NET Framework, as Entity Framework 6 doesn't support . NET Core. If you need cross-platform features you will need to upgrade to Entity Framework Core.

Is .NET core a console app?

Net Core Console app is cross platform, meaning it can run on macOS, Linux and Windows machines and . Net Framework Console app can only run on windows machines.

Can I use EF core with .NET framework?

You can use EF Core in APIs and applications that require the full . NET Framework, as well as those that target only the cross-platform .


1 Answers

The previous way you wrote the code (using) was never a good idea. Your context should be request-scoped; using using can lead to all sorts of issues with entity tracking and totally destroys all the helpful caching EF does. The best method for getting a context instance was always dependency injection via a DI container.

ASP.NET Core uses dependency injection for everything, and because of this EF Core's DbContext is designed to be dependency injected. In this regard, it no longer uses a default constructor out of the box, which is why your old code is failing (it depends on there being a default constructor).

Long and short, do things right and inject your context. It looks like you're attempting to do this based on your update. However, you cannot inject into something like Program. This is the entry point for your application, which means literally nothing exists yet. If you take a look at your web app, you'll notice that Program there sets up the web host builder (using Startup) and then builds and runs it. Behind the scenes this is doing a bunch of stuff, including setting up the service collection. This is what you need to do in your console app (set up the service collection). That's relatively straight forward:

class Program
{
    static void Main(string[] args)
    {
        var serviceProvider = new ServiceCollection()
            .AddDbContext<ApplicationDbContext>(o =>
                o.UseSqlServer("connection string"))
            .BuildServiceProvider();

        var context = serviceProvider.GetRequiredService<ApplicationDbContext>();

        new ExecutionEngine(context).Run();
    }
}

Now, this is a bit of overkill just based on the code you have here. You can simply new up an instance of your context via DbContextOptionsBuilder:

var options = new DbContextOptionsBuilder<ApplicationDbContext>()
    .UseSqlServer("connection string")
    .Options;
var context = new ApplicationDbContext(options);

However, using the service collection allows you to handle more advanced scenarios and better reuse your instances of things like your context across your codebase. Also it's worth mentioning that you should probably consider integrating configuration providers as well, so you don't need to hardcode your connection string. That's also relatively straight-forward:

var config = new ConfigurationBuilder()
    .SetBasePath(Path.Combine(AppContext.BaseDirectory))
    .AddJsonFile("appsettings.json", optional: true)
    .Build();

You might also want to add environment-specific configuration:

var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

Then:

.AddJsonFile($"appsettings.{environment}.json", optional: true);

This is just the same as doing all this in a web app, so you can add whatever type of configuration you like.

like image 152
Chris Pratt Avatar answered Oct 17 '22 12:10

Chris Pratt