Контекст равен нулю на уровне доступа к данным при использовании n-уровневой архитектуры в Web API, Entity Framework

#c# #entity-framework #asp.net-core-webapi #dbcontext

#c# #entity-framework #asp.net-core-webapi #dbcontext

Вопрос:

Я пытаюсь создать веб-API. Я использую Entity Framework здесь, подход code first.

Это n-уровневая архитектура. Это означает, что я создал несколько проектов в одном решении, как показано ниже.

введите описание изображения здесь

У меня есть метод контроллера, который является методом get. Я передам userid в качестве параметра.

 [Route("api/[controller]")]
[ApiController]
public class BankController : ControllerBase
{
    private readonly IBankApplicationDAL _bankAPI;

    public BankController(IBankApplicationDAL bankAPI)
    {
        _bankAPI = bankAPI;
    }

    [HttpGet("{userId}")]
    public IActionResult GetAccountDetailsId(int userId)
    {
        try
        {
            var values = _bankAPI.GetAccountDetailsId(userId);
            return Ok(values);
        }
        catch
        {
            throw;
        }
    }
}
  

На уровне DAL это то, что у меня есть:

 using BankApplicationAPI.Model;
using BankApplicationAPI.Data;
using System;
using System.Linq;

namespace BankApplicationAPI.DAL
{
    public class BankApplicationDAL : IBankApplicationDAL
    {
        DataContext context;

        public AccountDetails GetAccountDetailsId(int userId)
        {
            try
            {
                var values = context.AccountDetails.FirstOrDefault(x => x.UserId == userId); // context is null here.
                return values;
            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }
}
  

Это DataContext то, что у меня есть:

 namespace BankApplicationAPI.Data
{
    public class DataContext : DbContext
    {
        public DataContext(DbContextOptions<DataContext> options) : base(options) { }

        public DbSet<AccountDetails> AccountDetails { get; set; }
        public DbSet<TransactionDetails> TransactionDetails { get; set; }
    }
}
  

Когда я запускаю это приложение, я получаю исключение, в котором говорится, что контекст равен нулю в методе DAL (где я поместил комментарий).

Как мне создать объект для DataContext ? Кто-нибудь может мне здесь помочь? Это очень важно. Большое вам спасибо.

Редактировать

Startup.cs

 public void ConfigureServices(IServiceCollection services)
{
    var connection = @"Server=.sqlexpress;Database=AppDB;Trusted_Connection=True;ConnectRetryCount=0";

    services.AddDbContext<DataContext>(x => x.UseSqlServer(connection));
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    services.AddSingleton<IBankApplicationDAL, BankApplicationDAL>();
}
  

Комментарии:

1. Взгляните на свой BankApplicationDAL класс. Вы никогда не присваиваете значение своему личному context полю, поэтому оно null по умолчанию. Чего вы ожидаете?

2. @vasily.sib, да, я не присвоил значение контекстному полю. Как мне присвоить значение — вот мой вопрос. Если вы можете мне в этом помочь, я был бы признателен.

3. @hassan.ef опубликовал правильный ответ на этот вопрос

Ответ №1:

вы должны использовать это изменение:

  public class BankApplicationDAL : IBankApplicationDAL
 {
            DataContext _context;
            public BankApplicationDAL(DataContext context)
            {
                _context = context;
            }

            public AccountDetails GetAccountDetailsId(int userId)
            {
                try
                {
                    var values = context.AccountDetails.FirstOrDefault(x => x.UserId == userId); // context is null here.
                    return values;
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
   }
  

Комментарии:

1. Спасибо за ваш любезный ответ. Я попробовал то, что вы дали. Я получаю это исключение: при обработке запроса произошло необработанное исключение. Исключение InvalidOperationException: невозможно использовать службу с ограниченной областью действия «BankApplicationAPI.Data.DataContext» из одноэлементного «BankApplicationAPI.DAL.IBankApplicationDAL». Майкрософт. Расширения. DependencyInjection. ServiceLookup. CallSiteValidator . VisitScoped(ScopedCallSite scopedCallSite, состояние CallSiteValidatorState)

2. добавляете ли вы BankApplicationDAL и IBankApplicationDAL при запуске?

3. Я добавил startup.cs для вашей справки. Я что-то упускаю в этом?

4. Посмотрите, ваша DataContext область действия ограничена, что означает, что для каждого запроса будет новый экземпляр DataContext . Ваш IBankApplicationDAL одноэлементный , что означает, что он будет создан только один раз. Вы видите это сейчас? При любых запросах (кроме первого) ваш IBankApplicationDAL экземпляр будет содержать устаревший экземпляр DataContext . Это именно то, о чем вам сообщает сообщение exeption.

5. @CrazyCoder все в порядке. Зависимость с ограниченной областью действия означает, что она будет создана для области действия запроса (каждый запрос будет иметь свой собственный экземпляр этой зависимости с ограниченной областью действия). Просто замените services.AddSingleton<IBankApplicationDAL, BankApplicationDAL>(); на services.AddScoped<IBankApplicationDAL, BankApplicationDAL>();