Home > Software engineering >  Saving Data to MySQL using Pomelo Entity Framework
Saving Data to MySQL using Pomelo Entity Framework

Time:07-01

I applied the Migration and can see the tables in HeidiSQL but still get the error when trying to SaveChanges()

System.InvalidOperationException: 'A relational store has been configured without specifying either the DbConnection or connection string to use.'

LoadingInstruction.cs

using System.ComponentModel.DataAnnotations;

namespace NectarWarehouseAppServer.Models
{
    public class LoadingInstruction
    {
        [Key]
        public int? LoadingInstructionRecordId { get; set; }
        public string RouteId { get; set; }
        public string SalesOrderId { get; set; }       
        public int? LoadersTeamId { get; set; }
    }
}

LoadingInstructionContext.cs

using Microsoft.EntityFrameworkCore;
using System.Diagnostics.CodeAnalysis;
using NectarWarehouseAppServer.Models;

namespace NectarWarehouseAppServer.Models
{
    public class LoadingInstructionContext : DbContext
    {

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

        public LoadingInstructionContext()
        {
        }

        public DbSet<LoadingInstruction> LoadingInstruction { get; set; } = null!;


        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
             
            //Configuring the one to many relationship

            modelBuilder.Entity<LoadingInstruction>()
                    .HasKey(e => e.LoadingInstructionRecordId);
        }

      
         

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                IConfigurationRoot configuration = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json")
                    .Build();
                var connectionString = configuration.GetConnectionString("ConnectionString");
                optionsBuilder.UseMySql(ServerVersion.AutoDetect(connectionString), 
                   optionsBuilder => optionsBuilder.EnableRetryOnFailure(
                    maxRetryCount: 5,
                     maxRetryDelay: System.TimeSpan.FromSeconds(30),
                       errorNumbersToAdd: null));
            }
        }        
    }
}

ILoadingInstructionService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace NectarWarehouseAppServer.Models
{
    public interface ILoadingInstructionService
    {
        Task<int> Delete(int id);
        Task<IEnumerable<LoadingInstruction>> FindAll();
        Task<LoadingInstruction> FindOne(int id);
        Task<int> Insert(LoadingInstruction loadingInstruction);
        Task<int> Update(LoadingInstruction loadingInstruction);
      
    }
}

MariaDbContext.cs

using Microsoft.EntityFrameworkCore;
using System.Diagnostics.CodeAnalysis;
using NectarWarehouseAppServer.Models;

namespace NectarWarehouseAppServer.Models
{
    public partial class MariaDbContext : Microsoft.EntityFrameworkCore.DbContext
    {
        public MariaDbContext(DbContextOptions<MariaDbContext> options)
            : base(options)
        {
        }

        public virtual DbSet<Users> Users { get; set; }
        public virtual DbSet<LoadingInstruction> LoadingInstruction { get; set; }

     
    }
}

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },

  "ConnectionStrings": {
    "ConnectionString": "server=localhost;port=3306;database=****;uid=****;pwd=****;"
  }
}

Program.cs

using Microsoft.EntityFrameworkCore;
using NectarWarehouseAppServer.Models;
using NectarWarehouseAppServer.Services;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.


builder.Services.AddControllers();
builder.Services.AddDbContextPool<MariaDbContext>(opt =>
{
    opt.UseMySql(builder.Configuration.GetConnectionString("ConnectionString"),
     ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("ConnectionString")),
    builder =>
    {
        builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
    });
});




builder.Services.AddControllers();
builder.Services.AddDbContext<CustomerContext>(opt =>
{
    opt.UseMySql(builder.Configuration.GetConnectionString("ConnectionString"),
     ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("ConnectionString")),
    builder =>
    {
        builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
    });
});

builder.Services.AddScoped<IUsersService, UsersService>();
builder.Services.AddControllers();
builder.Services.AddDbContext<UsersContext>(opt =>
{
    opt.UseMySql(builder.Configuration.GetConnectionString("ConnectionString"),
     ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("ConnectionString")),
    builder =>
    {
        builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
    });
});


builder.Services.AddControllers();
builder.Services.AddDbContext<NectarWarehouseAppServer.Models.RouteContext>(opt =>
{
    opt.UseMySql(builder.Configuration.GetConnectionString("ConnectionString"),
     ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("ConnectionString")),
    builder =>
    {
        builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
    });
});

builder.Services.AddScoped<ILoadingInstructionService, LoadingInstructionService>();
builder.Services.AddControllers();
builder.Services.AddDbContext<LoadingInstructionContext>(opt =>
{
    opt.UseMySql(builder.Configuration.GetConnectionString("ConnectionString"),
     ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("ConnectionString")),
    builder =>
    {
        builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
    });
});

builder.Services.AddConnections();

var app = builder.Build();


// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
    //app.UseSwagger();
    //app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TodoApi v1"));
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

I tried several different configurations of the connection string such as using 'user' instead of 'uid' and 'password' instead of 'pwd', leaving out the port, etc.

This is where I get the error

  try
            {
                await using (LoadingInstructionContext dbContext = new LoadingInstructionContext())
                {

                     foreach (var loading in loadingInstructions){
                           LoadingInstruction loadingInstruction = new LoadingInstruction();
                           loadingInstruction.RouteId = "Route1";
                           loadingInstruction.SalesOrderId = "Order1";
                           loadingInstruction.LoadersTeamId = 0;
                           dbContext.Add(loadingInstruction);
                           dbContext.SaveChanges();
                       }


                    LoadingInstruction loadingInstruction = new LoadingInstruction();
                    dbContext.Add(loadingInstruction);
                    dbContext.SaveChanges();

                }

                return Ok();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return BadRequest(ex.ToString());
            }            

CodePudding user response:

It is because you did not send the connectionstring

LoadingInstructionContext.cs:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            IConfigurationRoot configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .Build();
            var connectionString = configuration.GetConnectionString("ConnectionString");
            optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)); /*send connectionstring with other params*/
        }
    }    

The DbContextOptions can be supplied to the DbContext by overriding the OnConfiguring method or externally via a constructor argument.

If both are used, OnConfiguring is applied last and can overwrite options supplied to the constructor argument.

so when you call your OnConfiguring your connectionstring will be overwrited. You can check your optionsBuilder on debug mode and see connectionString value

  • Related