Entity Framework Core使用多个DbContext

54

我遇到了一个问题,当我尝试访问我的PartsDbContext中的字段时,我会收到以下错误:

System.Data.SqlClient.SqlException:“Invalid object name 'fieldName'”

似乎这是因为我尝试让我的PartsDbContext使用与我的ApplicationDbContext相同的数据库,而该数据库用于Identity。我需要知道如何设置第二个dbcontext以与使用/创建不同数据库的EF核心一起工作。

我尝试创建第二个连接字符串,但我得到以下错误:

System.Data.SqlClient.SqlException:“无法打开请求的数据库“PartsDb”。登录失败。登录失败的用户为'DESKTOP-4VPU567\higle'。”

以下是我的代码:

appsettings.json

"ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-PrecisionCustomPC-b14db89e-86ad-4855-a17f-ac64a04339aa;Trusted_Connection=True;MultipleActiveResultSets=true",
    "PartsConnection":  "Server=(localdb)\\mssqllocaldb;Database=PartsDb"
},
"Logging": {
    "IncludeScopes": false,
    "LogLevel": {
        "Default": "Warning"
    }
}

PartsDbContext.cs

public class PartsDbContext : DbContext
{
    public DbSet<PartsViewModels.Tower> Towers { get; set; }
    public DbSet<PartsViewModels.Motherboard> Motherboards { get; set; }

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

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddDbContext<ApplicationDbContext>(options =>
         options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    services.AddEntityFramework()
        .AddDbContext<PartsDbContext>(options =>
          options.UseSqlServer(Configuration.GetConnectionString("PartsConnection")));

    services.AddMvc();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("RequireAdminRole", policy => policy.RequireRole("Admin"));
    });

    // Add application services.
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddTransient<ISmsSender, AuthMessageSender>();
}

AdminController.cs

[Authorize(Policy = "RequireAdminRole")]
public class AdminController : Controller
{
    private readonly PartsDbContext _context;

    public AdminController(PartsDbContext context)
    {
        _context = context;
    }

    public IActionResult Index()
    {
        return View();
    }

    public IActionResult Towers()
    {
        var model = _context.Towers.ToList();
        return View(model);
    }
}

错误出现在这行代码:var model = _context.Towers.ToList();

再次说明,我想要设置我的PartsDbContext以便与Entity Framework Core一起工作,以便EF-Core可以自动创建数据库。


你能否将 "PartsConnection": "Server=(localdb)\\mssqllocaldb;Database=PartsDb" 替换为 "PartsConnection": "Server=(localdb)\\mssqllocaldb;Database=PartsDb;Trusted_Connection=True" - Maria Ines Parnisari
4个回答

62

我找到解决方法了。这大部分是由于我不小心删除了Identity使用的数据库,所以我需要找出如何重新获取它。

显然,我的连接字符串本来就没什么问题。我只需要进入程序包管理器并按照以下顺序输入这些命令:

  1. Add-Migration init -Context PartsDbContext
  2. Update-Database -Context PartsDbContext

我发现这是因为我要让我的ApplicationDbContext再次工作,而这一步在使用Visual Studio创建新的MVC Core Web应用程序时使用个人用户验证时会由系统自动完成。

因此,添加更多的DbContexts的步骤是:

  1. 创建一个DbContext类
  2. appsettings.json中为该DbContext创建连接字符串
  3. 将DbContext添加到已配置的服务中,在Startup.cs中进行相关设置
  4. 在将使用它的控制器中设置DbContext
  5. 打开程序包管理器并运行上述2行代码。(如果“-Context”无效,请尝试“--context”)
  6. 运行您的程序,并让EntityFrameworkCore来处理其余的操作。

2
你是否在使用多个数据库中的同一个数据库?如果是这样,那么你如何在 EFMigrationsHistory 表中为每个上下文分离迁移? - dotnethaggis
1
我正在使用多个数据库。 - Joe Higley
2
如果在启动时有一个环境条件来确定给定上下文要使用哪个appsettings.json连接字符串,那该怎么办呢?你怎么知道pm控制台将使用哪一个? - DiscipleMichael
1
你是否在Git项目或类似的地方更好地解释了所有这些步骤? - Alexandra Damaschin
1
你知道是否有一种方法可以设置默认的DbContext吗?这样你就不需要每次都输入-context了吗? - Connor Knabe
显示剩余3条评论

4

首先感谢 @Joe Higley 回答了这个问题,我想添加更多情况来帮助更多人。

我的情况是我正在尝试使用EF-IdentityArea来创建一个管理员面板,在我的管理员区域拥有自己的controller/models/views...,同时也包含了一个新的DBcontext。

存在问题,如果您尝试使用context.Database.EnsureCreated();来初始化数据库,会出现以下错误:

System.Data.SqlClient.SqlException:'Invalid object name 'fieldName''

参考此链接Migrations with Multiple Providers

我们可以使用迁移并使用 --context 来设置要运行的 DbContext

在 VScode 中,您可以运行以下命令:

dotnet ef migrations add InitialCreate --context BlogContext
dotnet ef database update

在“程序包管理控制台”中,您可以运行以下命令:

Add-Migration InitialCreate -Context BlogContext
Update-Database

3
除了之前的评论,你还可以使用以下方法:

此外,您可以使用以下方式:

dotnet ef migrations add InitialCreate --context MyContext

dotnet ef database update --context MyContext

或者

Add-Migration InitialCreate -Context MyContext

Update-Database -Context MyContext

1
我还不能发表评论,但我想添加一个答案。
目前我正在完成这个教程:https://learn.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/model?view=aspnetcore-5.0&tabs=visual-studio 但我也是从ApplicationDbContext开始使用Identity的。所以,我遇到了类似的问题。你的答案帮了我很大忙,谢谢!
然而,教程建议用更干净的方法来解决这个问题。
  1. 添加数据模型
  2. 搭建数据模型!
这一步非常重要。它创建了Context类,在appsettings.json中配置连接字符串,在Startup.cs中添加了Context等等。 关于搭建的使用,请查看链接的教程。
  1. 在PMC中运行给定的命令即可。
    • Add-Migration init -Context ModelContext
    • Update-Database -Context ModelContext

因此,我建议使用脚手架工具,因为它可以为您完成大部分工作。


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