Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF Core with ASP MVC .NET 4.6

In a project I need to set up an ASP.NET MVC (with .NET 4.6.1) but using the "new" EF Core for accessing the database.

Unfortunately every documentation explains only how to setup an ASP.NET Core MVC project.

I just gave it a try and when it comes to creating the database via the Package Manager Console I get the error message:

No parameterless constructor was found on 'DataContext'. Either add a parameterless constructor to 'DataContext' or add an implementation of 'IDbContextFactory' in the same assembly as 'DataContext'

Yes, I don't have a parameterless constructor but neither does the example code of microsoft

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

I guess the problem is, that I don't register the DataContext in the Startup.cs which I don't have in an "old" ASP.NET MVC application.

Can anyone help me with this one?

like image 956
Baby Jesus Avatar asked May 24 '17 06:05

Baby Jesus


People also ask

What is ASP NET 4 6?

What is ASP.NET 4.6? ASP.NET 4.6 is an umbrella term used to describe updates existing Frameworks such as ASP.NET Web Forms/ MVC 5/ Web API 2 etc. You can build Web Apps using these Frameworks on the standard, desktop-enabled .NET Framework model.

What is EF Core in Entity Framework?

EF Core is an object-relational mapping (ORM) framework that simplifies the data access code. Model classes don’t have any dependency on EF Core. They just define the properties of the data that will be stored in the database. In this post, we will write the model classes first and EF Core will create the database.

What is the example of EF in MVC?

Example.MVC- reference Example.EF(MVC5). In Example.EF: Install EF Core, Microsft Dependency Injection. Create a class to support DI

How do I add EF Core support to a project?

About EF Core NuGet packages. To add EF Core support to a project, install the database provider that you want to target. This tutorial uses SQL Server, and the provider package is Microsoft.EntityFrameworkCore.SqlServer. This package is included in the Microsoft.AspNetCore.App metapackage, so you don't need to reference the package.


2 Answers

A simple example

  • Example.EF (.NET Standard project with EF Core and Microsoft Dependency Injection).
  • Example.Tools - reference Example.EF (.NET Core CommandLine project to run the migration only for the developer only).
  • Example.MVC - reference Example.EF (MVC5).

In Example.EF: Install EF Core, Microsft Dependency Injection. Create a class to support DI

public static class IocConfiguration
{
    public static void Configure()
    {
        var services = new ServiceCollection();

        services.AddDbContextPool<ExampleContext>(options => {
            options.UseSqlServer("_connectionstring_");
        });

        // Register to support the ExampleController can get DbContext.
        services.AddTransient(typeof(ExampleController));

        var serviceProvider = services.BuildServiceProvider();
        DependencyResolver.SetResolver(new DefaultServiceResolver(serviceProvider));
    }
}

public class DefaultServiceResolver : IDependencyResolver
{
    private readonly IServiceProvider _serviceProvider;

    public DefaultServiceResolver(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public object GetService(Type serviceType)
    {
        return _serviceProvider.GetService(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _serviceProvider.GetServices(serviceType);
    }
}

In the Example.MVC, with the Application_Start in Global.asax or Startup with Owin

// Register services.
IocConfiguration.Configure();

// Example controller
public class ExampleController : Controller 
{
     private readonly ExampleContext _exampleContext;

     public ExampleController(ExampleContext exampleContext)
     {
         _exampleContext = exampleContext;
     }
}

To run the migration:

Add-Migration {MigrationName} -Project Example.EF -StartupProject Example.Tools

We should have IDesignTimeDbContextFactory to support to run the migration.

like image 193
ocrenaka Avatar answered Sep 29 '22 09:09

ocrenaka


As per https://docs.microsoft.com/en-gb/ef/core/miscellaneous/cli/dbcontext-creation, you need to create a factory.

From a design-time factory

You can also tell the tools how to create your DbContext by implementing the IDesignTimeDbContextFactory<TContext> interface: If a class implementing this interface is found in either the same project as the derived DbContext or in the application's startup project, the tools bypass the other ways of creating the DbContext and use the design-time factory instead. C#

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;

namespace MyProject
{
    public class BloggingContextFactory : IDesignTimeDbContextFactory<BloggingContext>
    {
        public BloggingContext CreateDbContext(string[] args)
        {
            var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
            optionsBuilder.UseSqlite("Data Source=blog.db");

            return new BloggingContext(optionsBuilder.Options);
        }
    }
}

Note The args parameter is currently unused. There is an issue tracking the ability to specify design-time arguments from the tools.

A design-time factory can be especially useful if you need to configure the DbContext differently for design time than at run time, if the DbContext constructor takes additional parameters are not registered in DI, if you are not using DI at all, or if for some reason you prefer not to have a BuildWebHost method in your ASP.NET Core application's Main class.

You can't inject a connection string here, but it's not an issue since this is only used for design-time functionality like creating migrations.

like image 31
user247702 Avatar answered Sep 29 '22 10:09

user247702