update-database ef6 "Unable to create an object of type 'CMSDBContext'"

huangapple go评论69阅读模式
英文:

update-database ef6 "Unable to create an object of type 'CMSDBContext'"

问题

Here is the translated code part you provided:

<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);
    }
}

Registering services:

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;"

Error message:

Unable to create an object of type 'CMSDBContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

There were solutions about making the project as the startup project (already done and no success).

I tried to initially create an empty database with the database name and tried again, but no success.

Pretty sure that the code has no issues because it was working previously on other machines, but what would be the possible issue causing this problem?

I installed Entity Framework Core, Entity Framework Core SQL Server, and Entity Framework Tools for the application layer and infrastructure layer, version 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>
英文:
&lt;ItemGroup&gt;
	&lt;PackageReference Include=&quot;Microsoft.EntityFrameworkCore&quot; Version=&quot;6.0.1&quot; /&gt;
	&lt;PackageReference Include=&quot;Microsoft.EntityFrameworkCore.SqlServer&quot; Version=&quot;6.0.1&quot; /&gt;
	&lt;PackageReference Include=&quot;Microsoft.EntityFrameworkCore.Tools&quot; Version=&quot;6.0.1&quot;&gt;
	  &lt;PrivateAssets&gt;all&lt;/PrivateAssets&gt;
	  &lt;IncludeAssets&gt;runtime; build; native; contentfiles; analyzers; buildtransitive&lt;/IncludeAssets&gt;
	&lt;/PackageReference&gt;
	&lt;PackageReference Include=&quot;Newtonsoft.Json&quot; Version=&quot;13.0.1&quot; /&gt;
	&lt;PackageReference Include=&quot;StackExchange.Redis&quot; Version=&quot;2.5.43&quot; /&gt;
&lt;/ItemGroup&gt;
public class CMSDBContext : DbContext
{
    public CMSDBContext(DbContextOptions&lt;CMSDBContext&gt; options)
                : base(options)
    {
    }

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

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

        foreach (var auditableEntity in ChangeTracker.Entries&lt;IAuditable&gt;())
        {
            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);
    }
}

Registering services:

public static IServiceCollection AddPresistenceInfrastructure(this IServiceCollection services)
{
    services.AddDbContext&lt;CMSDBContext&gt;(options =&gt; options.UseSqlServer(SettingManager.CMSConnectionString));

    #region Repositories
    services.AddTransient(typeof(IGenericRepository&lt;&gt;), typeof(GenericRepository&lt;&gt;));
    services.AddTransient(typeof(IReadonlyRepository&lt;&gt;), typeof(ReadonlyRepository&lt;&gt;));
    services.AddTransient(typeof(ISectionRepository), typeof(SectionRepository));
    #endregion

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

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

    services.AddSingleton&lt;ICacheService, RedisCacheService&gt;();
    #endregion

    return services;
}

appsettings.json:

&quot;CMSConnection&quot;: &quot;Server=Sandy-NB\\LOCALSERVER;Database=cms_db;User Id=sa;Password=xxxx;&quot;
PM&gt; Update-database --verbose
Build started...
Build succeeded.
Unable to create an object of type &#39;CMSDBContext&#39;. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

There were solutions about making the project as startup project (already done and no success)

I tried to initially create an empty database with the database name and tried again -- no success

Pretty sure that the code has no issues because it was working previously on other machines but what would be the possible issue causing this problem?

I installed Entity Framework Core, Entity Framework Core SQL Server, Entity Framework Tools for the application layer and infrastructure layer version 6.0.1

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

&lt;ItemGroup&gt;
	&lt;ProjectReference Include=&quot;..\..\Core\CMS.Application\CMS.Application.csproj&quot; /&gt;
	&lt;ProjectReference Include=&quot;..\..\Core\CMS.Domain\CMS.Domain.csproj&quot; /&gt;
	&lt;ProjectReference Include=&quot;..\..\Shared\CMS.Shared.Common\CMS.Common.csproj&quot; /&gt;
&lt;/ItemGroup&gt;

答案1

得分: 2

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

英文:

The simple answer was actually in the question, there were two different projects , the persistance layer Project and web api layer Project and of course the startup project should be the program.cs.

答案2

得分: 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 <知道如何配置您的DbContext依赖项的项目的绝对路径>

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

如果仍然无法使其工作,请尝试删除带有参数的构造函数,并重写OnConfigure(如果需要任何配置的话)。然后工具不需要能够解析您上下文的依赖关系,只需使用无参数构造函数进行实例化即可。

英文:

The error shows if the EF tools cannot determine how to build your DbContext (as stated by the error).

The docs for the command you find actually state -v or --verbose as command argument to show verbose output. The latter, --verbose, only works if you invoke the command from something like PowerShell. If you run from inside VisualStudio's PM Console, the correct argument is actually -verbose or -v and not --verbose (note the difference in dashes).

When using -verbose, it should tell you which project it finds and uses to initialize your DbContext.

Remember, since your CMBSContext has no parameterless constructor, the tool must know how to resolve the context's dependencies, and thus, the project it finds must build a host, where the host has configured all the necessary dependencies (as stated in the link description from the error output).

In case it resolves the wrong project I recommend using the EF tools from PowerShell instead (or whatever terminal you like), and then run something like the following:

dotnet tool install --global dotnet-ef
dotnet ef database update -v -s &lt;absolute-path-to-project-that-knows-how-to-configure-your-dbcontexts-dependencies&gt;

I don't know if you can do something similar from the Visual Studio's PM Console. Maybe if you look in the docs you can find it.

If you still cannot make it work try to remove the constructor with parameters, and override OnConfigure (if you need any configuration, that is). Then the tools don't need to be able to resolve your context's dependencies, and will just new it up with the parameterless constructor.

huangapple
  • 本文由 发表于 2023年7月27日 19:39:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76779359.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定