【问题标题】:Add Migration: Unable to create an object of type AppContext添加迁移:无法创建 AppContext 类型的对象
【发布时间】:2021-04-05 23:56:28
【问题描述】:

我有一个 .NET 5 解决方案,其中包含两个项目(DataLayer 和 ServiceLayer)。 在 DataLayer 我有以下 DbContext:

internal class ApplicationContext
    : DbContext
{
    public ApplicationContext(DbContextOptions<ApplicationContext> options)
        : base(options)
    {
    }
    public virtual DbSet<User> Users { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly);
    }
}

以及以下 DbContextFactory:

internal sealed class ContextFactory
    : IDbContextFactory<ApplicationContext>
{
    public ContextFactory(DbContextOptions<ApplicationContext> options)
    {
        Options = options ?? throw new ArgumentNullException(nameof(options));
    }

    private DbContextOptions<ApplicationContext> Options { get; }

    public ApplicationContext CreateDbContext()
    {
        return new ApplicationContext(Options);
    }
}

我在每个存储库 ctor 中使用:

 public UserRepository(IDbContextFactory<ApplicationContext> contextFactory) { ... }

以及 DbContextFactory 的服务初始化:

services.AddDbContextFactory<ApplicationContext>(options =>
{
    options
    .UseLazyLoadingProxies()
    .UseSqlServer(connectionString);
});

问题是当我尝试创建迁移时,我收到以下消息:

无法创建“ApplicationContext”类型的对象。对于设计时支持的不同模式,请参阅https://go.microsoft.com/fwlink/?linkid=851728 了解这两个命令:

添加迁移初始

dotnet ef 迁移添加 Initial--project DataLayer

我还必须提到,这两个项目都是普通的 .NET 5 库项目,并且在服务层项目中,我手动构建了 ServiceCollection:var services = new ServiceCollection();

我搜索了解决方案,但没有找到。

谢谢

【问题讨论】:

  • 如果是asp.net core,为什么还要使用ContextFactory?我的意思是上下文可以很容易地由 DI 在运行时通过启动来初始化。
  • @AVTUNEY 需要 ef 迁移工具 dotnet ef migrations ...
  • @mtkachenko 我知道并理解,但是这个人说他正在使用 Add-Migration。它自动意味着他在 windows 上使用 Visual Studio。我认为不需要 ef 核心工具包。如果是 VsMac,甚至是 Visual Studio Code,那么使用它是正确的。
  • @AVTUNEY dotnet ef migrations add .. 是一个跨平台。
  • @mtkachenko 我知道,在谈论他。

标签: c# dependency-injection entity-framework-core .net-5


【解决方案1】:

我认为你不能在构造函数中注入任何东西。你应该使用documentation中描述的方式:

public class BloggingContextFactory : IDesignTimeDbContextFactory<BloggingContext>
{
    public BloggingContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
        optionsBuilder.UseSqlite("Data Source=blog.db");

        return new BloggingContext(optionsBuilder.Options);
    }
}

然后你可以通过args传递任何参数:

dotnet ef database update -- --environment Production --connectionstring "some_connection_string"

【讨论】:

  • 更改为 IDesignTimeDbContextFactory 解决了这个问题,但是,我想知道如何以及何时使用 args(来自 CreateDbContext(string[] args) 方法)。
  • 只需阅读官方文档docs.microsoft.com/en-us/ef/core/cli/…(它实际上是您的错误的链接):The -- token directs dotnet ef to treat everything that follows as an argument and not try to parse them as options. Any extra arguments not used by dotnet ef are forwarded to the app. 同时检查我回答中示例中的参数
猜你喜欢
  • 2021-02-06
  • 2021-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-09
相关资源
最近更新 更多