起因

新创建一个项目,使用EntityFrameWorkCore,为图方便,直接从现有项目下,复制了appDbcontext类的文件,但在编译过程中,出现了各种奇怪问题。

看代码:

namespace EquipmentSys.Data
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {
        }
        public DbSet<Equipment> Equipments { get; set; } 
    }

迁移数据库时提示:
Add-Migration eq
Build started…
Build succeeded.
Unable to create a ‘DbContext’ of type ‘’. The exception ‘Unable to resolve service for type ‘Microsoft.EntityFrameworkCore.DbContextOptions`1[EquipmentSys.Data.ApplicationDbContext]’ while attempting to activate ‘EquipmentSys.Data.ApplicationDbContext’.’ was thrown while attempting to create an instance. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
找豆包,豆包建议:

namespace EquipmentSys.Data
{
    public class ApplicationDbContext : DbContext
    {        // 【关键】EF 迁移只认这个无参构造
        public ApplicationDbContext()
        {
        }
        // 正常运行用的构造(保留)
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
        // 【最重要】迁移时强制配置数据库,从 appsettings 读取
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                // 读取配置文件
                var config = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json")
                    .Build();

                var conn = config.GetConnectionString("DefaultConnection");
                optionsBuilder.UseSqlServer(conn);
            }
        }
        // 你的表 ↓
        // public DbSet<Equipment> Equipments { get; set; }
    }
}

按照豆包的建议修改,数据库迁移命令add-migration eq 能运行,看似能基本解决。数据库也迁移成功了。程序编译也成功了。但运行时出现问题
看Program.cs

using EquipmentSys.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// Add services to the container.
builder.Services.AddControllersWithViews();
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
   name: "default",
   pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();

在运行builder.Services.AddControllersWithViews();这句时,提示:System.InvalidOperationException:“The service collection cannot be modified because it is read-only.”
原来在app.builder运行之前, 必须加载所有服务。
将var app = builder.Build();放在加载服务之后,程序能正常运行了。

由此想到:会不会是var app = builder.Build();加载导致 public class ApplicationDbContext : DbContext不能正常迁移呢?

将代码改回:

namespace EquipmentSys.Data
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {
        }
        public DbSet<Equipment> Equipments { get; set; } 
    }

放弃豆包的提示代码,程序依旧照常运行。

原因分析:

1、因var app = builder.Build()运行在加载数据服务之前,导致DbContext无法识别。

2、豆包加载了public ApplicationDbContext()和 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)导致即使不注入builder.Services.AddDbContext

(options =>options.UseSqlServer(connectionString));迁移虽能运行,但不是正确的方法。由于服务没有注入,程序虽能正确编译,但程序无法运行。

3、所以最初导致数据库不能迁移的原因是app = builder.Build();运行之前未注入数据库服务。

结论:AI可以为编程提供很多方便,但问题的根源不一定能分析清楚。看来,还是人脑还比较可靠。

另外:数据库的迁移最少要以下库:

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Tools
同时要有版本要正确。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐