0

I am working on project with no repository pattern. I am trying to seperate my business logic from controllers, kind of setting up a business layer. I do the following to get all of my users.

DbContext

public class DatabaseContext : DbContext
{
    public DatabaseContext() : base() { }
    public DatabaseContext(DbContextOptions options) : base(options) { }
    public DbSet<User> Users { get; set; }
    public DbSet<OvertimeRequest> OvertimeRequests { get; set; }
    public DbSet<HolidayRequest> HolidayRequests { get; set; }
    public DbSet<PaymentRequest> PaymentRequests { get; set; }
}

OvertimeRequestBusiness

public class OvertimeRequestBusiness
{
    public static OvertimeRequestBusiness Instance { get; } = new 
        OvertimeRequestBusiness();

    public OvertimeRequestBusiness() { }

    public async Task<List<User>> GetAllUsersAsync()
    {
        using (var ctx = new DatabaseContext())
        {
            var query = ctx.Users;
            var res = await query.ToListAsync();
            return res;
        }
    }
}

Controller

[Route("users"), HttpGet]
public async Task<List<User>> GetAllUsers()
{
    return await OvertimeRequestBusiness.Instance.GetAllUsersAsync();
}

And the error I get is

InvalidOperationException: No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext**

3 Answers 3

1

Without changing the OvertimeRequestBusiness is to set db connection string in OnCongfiguring method of DbContext class :

  1. Setting connect string in `appsettings.json :

    "ConnectionStrings": {
        "MyConnectionString": "Server=(localdb)\\mssqllocaldb;Database=RazorPagesMovieContext-1234;Trusted_Connection=True;MultipleActiveResultSets=true"
    },
    
  2. Create Setting.cs :

    public class Setting
    {
        public static string ConnectionString { get; set; }
    }
    
  3. Config the connectstring in Startup.cs:

    Setting.ConnectionString = Configuration.GetSection("ConnectionStrings:MyConnectionString").Value;
    
  4. Modify the DatabaseContext:

    public class DatabaseContext : DbContext
    {
    
          public DbSet<User> Users { get; set; }
          public DbSet<OvertimeRequest> OvertimeRequests { get; set; }
          public DbSet<HolidayRequest> HolidayRequests { get; set; }
          public DbSet<PaymentRequest> PaymentRequests { get; set; }
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder.UseSqlServer(Setting.ConnectionString);
            }
        }
    
    }
    

But the common way is to use DbContext with dependency injection :

https://learn.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext

Sign up to request clarification or add additional context in comments.

Comments

0

Your DatabaseContext constructor needs to point to the connection string.

Change it to be

public class DatabaseContext : DbContext
{
    // Tell DbContext to look for the "MyConnectionString" in .config.
    public DatabaseContext() : base("MyConnectionString") { }

    public DatabaseContext(DbContextOptions options) : base(options) { }

    public DbSet<User> Users { get; set; }
    public DbSet<OvertimeRequest> OvertimeRequests { get; set; }
    public DbSet<HolidayRequest> HolidayRequests { get; set; }
    public DbSet<PaymentRequest> PaymentRequests { get; set; }
}

Where your connection string is in web.config

<configuration>
    <connectionStrings>
        <add name="MyConnectionString" providerName="System.Data.SqlClient" connectionString="Server=.\SQLEXPRESS;Initial Catalog=ABC;Integrated Security=True;MultipleActiveResultSets=true"></add>
    </connectionStrings>
</configuration>

Comments

0

I deleted the default parameterless constructor of DbContext and then passed the DbContextBuilderOption as parameter in OvertimeRequestBusiness. This did the trick for me.

OvertimeRequestBusiness Looks like this now

 public class OvertimeRequestBusiness
    {
        public static OvertimeRequestBusiness Instance { get; } = new OvertimeRequestBusiness();

        DbContextOptionsBuilder<DatabaseContext> _optionsBuilder;


        public OvertimeRequestBusiness() {
            var optionsBuilder = new DbContextOptionsBuilder<DatabaseContext>();
            optionsBuilder.UseSqlServer(@"ConnectionString");
            _optionsBuilder = optionsBuilder;
        }
  public async Task<List<User>> GetAllUsersAsync()
        {
            using (var ctx = new DatabaseContext(_optionsBuilder.Options))
            {
                var query = ctx.Users;
                var res = await query.ToListAsync();
                return res;
            }
        }

    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.