更新数据库 ef6 "无法创建类型为 'CMSDBContext' 的对象"

3
<ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.1">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
    <PackageReference Include="StackExchange.Redis" Version="2.5.43" />
</ItemGroup>

public class CMSDBContext : DbContext
{
    public CMSDBContext(DbContextOptions<CMSDBContext> options)
                : base(options)
    {
    }

    // Dbsets
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("dbo");
        base.OnModelCreating(modelBuilder);
        CustomDateConverter.DateToUTC(modelBuilder);
        modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
    }

    public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
    {
        DateTime currentDateTime = DateTime.UtcNow;

        foreach (var auditableEntity in ChangeTracker.Entries<IAuditable>())
        {
            if (auditableEntity.State == EntityState.Added || auditableEntity.State == EntityState.Modified)
            {
                switch (auditableEntity.State)
                {
                    case EntityState.Added:
                        auditableEntity.Entity.CreatedAt = currentDateTime;
                        break;

                    case EntityState.Modified:
                        auditableEntity.Entity.UpdatedAt = currentDateTime;
                        break;
                }
            }
        }

        return await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
    }
}

注册服务:
public static IServiceCollection AddPresistenceInfrastructure(this IServiceCollection services)
{
    services.AddDbContext<CMSDBContext>(options => options.UseSqlServer(SettingManager.CMSConnectionString));

    #region Repositories
    services.AddTransient(typeof(IGenericRepository<>), typeof(GenericRepository<>));
    services.AddTransient(typeof(IReadonlyRepository<>), typeof(ReadonlyRepository<>));
    services.AddTransient(typeof(ISectionRepository), typeof(SectionRepository));
    #endregion

    #region Cache
    var redisConfigSection = SettingManager.GetSection(RedisSettings.SectionName);

    services.AddSingleton<IConnectionMultiplexer>(sp => ConnectionMultiplexer.Connect(new ConfigurationOptions
            {
                EndPoints = { $"{redisConfigSection["Server"]}:{redisConfigSection["Port"]}" },
                AllowAdmin = true,
                AbortOnConnectFail = false,
            }));

    services.AddSingleton<ICacheService, RedisCacheService>();
    #endregion

    return services;
}

appsettings.json:

"CMSConnection": "Server=Sandy-NB\\LOCALSERVER;Database=cms_db;User Id=sa;Password=xxxx;"

PM> Update-database --verbose
Build started...
Build succeeded.
Unable to create an object of type 'CMSDBContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

关于将项目作为创业项目的解决方案已经尝试过了,但没有成功。

我尝试了最初创建一个空数据库,并使用数据库名称再次尝试,但仍然没有成功。

我相当确定代码没有问题,因为在其他机器上之前是可以工作的,那么可能导致这个问题的可能原因是什么呢?

我安装了Entity Framework Core、Entity Framework Core SQL Server、Entity Framework Tools的应用程序层和基础设施层版本为6.0.1。

<ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.1">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
    <PackageReference Include="StackExchange.Redis" Version="2.5.43" />
</ItemGroup>

<ItemGroup>
    <ProjectReference Include="..\..\Core\CMS.Application\CMS.Application.csproj" />
    <ProjectReference Include="..\..\Core\CMS.Domain\CMS.Domain.csproj" />
    <ProjectReference Include="..\..\Shared\CMS.Shared.Common\CMS.Common.csproj" />
</ItemGroup>
2个回答

2
简单的答案实际上就在问题中,有两个不同的项目,持久层项目和Web API层项目,当然启动项目应该是program.cs。

欢迎来到SO Sandy。您可以将自己的答案标记为解决方案。如果其他答案对您有帮助,请记得点赞。 :) - Kristin
欢迎来到SO Sandy。你可以将自己的答案标记为解决方案。如果其他答案对你有帮助,请记得点赞。:) - undefined
在选择主机浏览时,应选择API项目,而在包管理器控制台中,请确保选择了持久化项目。 - Sandy

0

如果EF工具无法确定如何构建您的DbContext,则会显示错误信息。

实际上,您找到的命令文档中指定了-v--verbose作为命令参数以显示详细输出。后者--verbose只在从类似PowerShell的环境中调用命令时有效。如果您在VisualStudio的PM控制台中运行,则正确的参数实际上是-verbose-v而不是--verbose(请注意破折号的差异)。

使用-verbose时,它应该告诉您找到并用于初始化DbContext的项目。

请记住,由于您的CMBSContext没有无参数的构造函数,因此工具必须知道如何解析上下文的依赖关系,因此找到的项目必须构建一个主机,其中配置了所有必要的依赖项(如错误输出中的链接描述所述)。

如果解析错误的项目,我建议改用PowerShell等终端中的EF工具,然后运行以下命令:

dotnet tool install --global dotnet-ef
dotnet ef database update -v -s <absolute-path-to-project-that-knows-how-to-configure-your-dbcontexts-dependencies>

我不知道你是否可以从Visual Studio的PM控制台执行类似的操作。也许如果你查看文档,你能找到。

如果你仍然无法使其工作,请尝试移除带参数的构造函数,并重写OnConfigure(如果你需要任何配置的话)。然后工具就不需要解析你上下文的依赖项,而只会用无参数构造函数新建它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接