EF Core, как получить DBContext в экземпляре класса? - PullRequest
0 голосов
/ 20 февраля 2019

В проекте ASP NET Core используется Entity Framework Core.

Из метода контроллера Home я вызываю Task.Run для метода экземпляра класса MyClass, где мне нужно получить доступданные из базы данных.

Я пытался передать _dbContext в конструктор класса MyClass, но получаю исключение

Невозможно получить доступ к удаленному объекту.

HomeController

[Route("api/[controller]")]
[EnableCors("AllowAllOrigin")]
[ApiController]
public class HomeController : ControllerBase
{
   private readonly DataBaseContext _dbContext;

   public HomeController (DataBaseContext dbContext)
   {
      _dbContext = dbContext;
   }

   [EnableCors("AllowAllOrigin")]
   [HttpPost("[action]")]
   public string UpdateBotSettings()
   {
      MyClass myClass = new MyClass(_dbContext);
      Task task = Task.Run(() => myClass.AnyMethod());
   }
}

MyClass

public class MyClass
{
   private readonly DataBaseContext _dbContext;

   public MyClass(DataBaseContext dbContext)
   {
      _dbContext = dbContext;
   }

   public async void AnyMethodAsync()
   {
      MyData myData = _dbContext.AnyData.Where(d => d.id == 1).FirstOrDefault(); // <- exception
   }
}

Запуск

public void ConfigureServices(IServiceCollection services)
{
  services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

  string connection = Configuration.GetConnectionString("ConnectionDB");
  services.AddDbContext<DataBaseContext>(options =>  options.UseSqlServer(connection));
  // another code
}

Подскажите, пожалуйста, как получить доступ к dbContext внутри экземпляра MyClass?

1 Ответ

0 голосов
/ 20 февраля 2019

Самая важная ошибка в вашем коде заключается в том, что вы используете async void в вашем AnyMethodAsync() методе Myclass.Не используйте async void в своем коде, вместо этого используйте async Task.Вот подробности: C # - остерегайтесь асинхронной пустоты в вашем коде

Итак, напишите свой AnyMethodAsync() следующим образом:

public async Task AnyMethodAsync()
{
   MyData myData = await _dbContext.AnyData.Where(d => d.id == 1).FirstOrDefault(); 
}

Теперь вы можете зарегистрировать свой MyClass в контейнер ASP.NET Core DI следующим образом:

public void ConfigureServices(IServiceCollection services)
{
   services.AddScoped<MyClass>(); // <-- here it is

   string connection = Configuration.GetConnectionString("ConnectionDB");
   services.AddDbContext<DataBaseContext>(options =>  options.UseSqlServer(connection));
   // another code
   services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Теперь используйте его следующим образом:

[Route("api/[controller]")]
[EnableCors("AllowAllOrigin")]
[ApiController]
public class HomeController : ControllerBase
{
   private readonly DataBaseContext _dbContext;
   private readonly MyClass _myClass

   public HomeController (DataBaseContext dbContext, MyClass myClass)
   {
      _dbContext = dbContext;
      _myClass = myClass;
   }

   [EnableCors("AllowAllOrigin")]
   [HttpPost("[action]")]
   public async Task<string> UpdateBotSettings()
   {
      await _myClass.AnyMethod();

      // rest of codes
   }
}
...