Как настроить DbContext с внедрением зависимостей в .Net Core 2.1? - PullRequest
0 голосов
/ 05 декабря 2018

Служба

public void ConfigureServices(IServiceCollection services)
{
    string cs = Configuration.GetConnectionString("Skillcheck"); 
    services.AddDbContext<TicketsystemContext>(options => options.UseSqlServer(cs));
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

Контекст

public TicketsystemContext()
{
}

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

// ... rest of the context

Исключение

System.InvalidOperationException: для этого DbContext не настроен поставщик базы данных.Поставщик может быть настроен путем переопределения метода DbContext.OnConfiguring или с помощью AddDbContext в поставщике службы приложений.Если используется AddDbContext, то также убедитесь, что ваш тип DbContext принимает объект DbContextOptions в своем конструкторе и передает его базовому конструктору для DbContext.в Microsoft.EntityFrameworkCore.Internal.DbContextServices.Initialize (ISopviceProvider scopedProvider, IDbContextOptions contextOptions, контекст DbContext)
в Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider.PropertyHelper.CallNullSafePropertyGetter [TDeclaringType, TValue] (метод получения Func`2, объектная цель) в Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinder.BinderModelCoreAsync (actionBindingContext.Conject.Bext.Text.NET)., IModelBinder modelBinder, IValueProvider valueProvider, параметр ParameterDescriptor, метаданные ModelMetadata, значение объекта)
в Microsoft.AspNetCore.Mvc.Internal.ControllerBinderDelegateProvider. <> C__DisplayClass0_0.d.MoveNext ()

Исключение при удалении пустого конструктора из контекста

System.InvalidOperationException: Не удалось создать экземпляр типа 'Skillcheck.Models.TicketsystemContext».Сложные типы, связанные с моделью, не должны быть абстрактными или значениями и должны иметь конструктор без параметров.В качестве альтернативы, дайте параметру 'c' ненулевое значение по умолчанию.по адресу Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinder.CreateModel (ModelBindingContext bindingContext) по адресуactionContext, IModelBinder modelBinder, IValueProvider valueProvider, параметр ParameterDescriptor, метаданные ModelMetadata, значение объекта)
в Microsoft.AspNetCore.Mvc.Internal.ControllerBinderDelegateProvider. <> c__DisplayClass0_0.d.MoveNext ()

  • cs в Сервисе не является нулевым и успешно читает строку из appsettings.json
  • после services.AddDbContext контекст находится в ServiceCollectionи он не выдает
  • с использованием универсальных DbContextOptions вместо DbContextOptions в конструкторе контекста не работает
  • явное добавление IHttpContextAccessor не работает либо

Я временно решил это, переопределив OnConfiguring, но я хочу понять, почему он не работает.Я использую .Net Core 2.1 на VS2017.

Решение

Ошибка была в том, что вместо

private TicketsystemContext _c;

public HomeController(TicketsystemContext c)
{
    _c = c;
}

public IActionResult Index()
{
    return View(_c.User.First());
}

я использовал

public IActionResult Index(TicketsystemContext c)
{
    return View(c.User.First());
}

, который работает при переопределении OnConfiguring, но не при настройке при инъекции.

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Вы вводите TicketsystemContext в действие Index напрямую.

В общем, вы должны ввести TicketsystemContext как зависимость в конструктор, как показано ниже:

public class HomeController : Controller
{
    private readonly TicketsystemContext context;
    public HomeController(TicketsystemContext context)
    {
        this.context = context;
    }
    public IActionResult Index()
    {
        return View(context.User.First());
    }
}

Если вы предпочитаете вводить TicketsystemContext в действие, вы можете попробовать предложение из @Chris Prattпо коду ниже:

public IActionResult Index([FromServices]TicketsystemContext c)
{
    return View(c.User.First());
}
0 голосов
/ 05 декабря 2018

Ну, первая ошибка связана с включением конструктора без параметров.Это не должно присутствовать.Внедрение зависимостей всегда будет выбирать конструктор с наименьшим количеством зависимостей для удовлетворения, который будет без параметров, но вам нужно DbContextOptions<TContext> внедрить.

Вторая ошибка означает, что вы включаетеконтекст как параметр в методе действия.Я не уверен, почему ты это делаешь, но ты не должен.Ваш контекст должен быть введен в сам контроллер и установлен на ivar, чтобы ваши действия могли использовать ivar.Вы можете иметь возможность поставить префикс перед параметром [FromServices], чтобы указать, что связыватель моделей должен его игнорировать и вместо этого он должен быть внедрен из коллекции сервисов, но внедрение метода является анти-паттерном.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...