Home > other >  MySQL AddDbContext on Startup class
MySQL AddDbContext on Startup class

Time:09-16

I'm having some problems trying to connect to MySQL with .Net Core. It connects fine if I use the OnConfiguring overriding on DatabaseContext. But can't connect with the AddDbContext on Startup...

appsettings.json:

{
  "ConnectionStrings": {
    "Default": "server=localhost,3306;initial catalog=shoppy;user id=sa;password=xxxx;convert zero datetime=true"
  },
...
}

Startup.cs:

...
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<DatabaseContext>(
        context => context.UseMySql(Configuration.GetConnectionString("Default"), Microsoft.EntityFrameworkCore.ServerVersion.Parse("8.0.26-mysql"))
    );
    ...
}

DatabaseContext.cs

public partial class DatabaseContext : DbContext
{
    public DatabaseContext() { }

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

// protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
//        {
//            if (!optionsBuilder.IsConfigured)
//            {
//#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
//                optionsBuilder.UseMySql("server=localhost,3306;initial catalog=shoppy;user id=sa;password=xxxx;convert zero datetime=true", Microsoft.EntityFrameworkCore.ServerVersion.Parse("8.0.26-mysql"));
//            }
//        }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
{ 
    if (!optionsBuilder.IsConfigured)
    { }
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    ...
}

partial void OnModelCreatingPartial(ModelBuilder modelBuilder);

service method:

public Admin Get(Expression<Func<Admin, bool>> predicate = null)
{
    try
    {
        using (var context = new DatabaseContext())
        {
            return context.Set<Admin>()
                // If return null, throw an exception
                .FirstOrDefault(predicate ?? throw new ArgumentException(nameof(predicate)));
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return null;
    }
            
}

Throws the following exception:

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 object in its constructor and passes it to the base constructor for DbContext.

csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="5.0.9" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.9" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.9">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.9" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.9">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
    <PackageReference Include="MySql.Data" Version="8.0.26" />
    <PackageReference Include="MySql.EntityFrameworkCore" Version="5.0.5" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\BL\BL.csproj" />
    <ProjectReference Include="..\DAL\DAL.csproj" />
    <ProjectReference Include="..\Entities\Entities.csproj" />
    <ProjectReference Include="..\Interfaces\Interfaces.csproj" />
    <ProjectReference Include="..\Services\Services.csproj" />
  </ItemGroup>

  <ItemGroup>
    <Folder Include="Areas\Admin\Data\" />
  </ItemGroup>

</Project>

CodePudding user response:

Add new constructor to your DBContext class.

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

Inject context to your controllers:

public class MyController
{
    private readonly DatabaseContext_context;

    public MyController(DatabaseContext context)
    {
      _context = context;
    }

    ...
}

as advised in the error message:

If 'AddDbContext' is used, then also ensure that your DbContext type accepts a DbContextOptions object in its constructor and passes it to the base constructor for DbContext.

CodePudding user response:

Thanks to @Chaodeng, I've managed to find the solution:

public class AdminService : IAdminService
{
    private readonly DatabaseContext _databaseContext;

    public AdminService(DatabaseContext databaseContext)
    {
        this._databaseContext = databaseContext;
    }

    ...

    public Admin Get(Expression<Func<Admin, bool>> predicate = null)
    {
        try
        {
            var context = this._databaseContext.Set<Admin>()
                    // If return null, throw an exception
                    .FirstOrDefault(predicate ?? throw new         
                        ArgumentException(nameof(predicate)));
            return context;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return null;
        }
    }
}
  • Related