简体   繁体   English

带有EF Core的.NET Core 2在同一数据库(SQL Server)中具有不同架构的不同上下文

[英].NET Core 2 with EF Core different contexts with different schemas in same DB(SQL Server)

I would like to have my tables in a C# ASP.NET Core 2 application in two separate schemas. 我想在两个单独的架构中将表放在C#ASP.NET Core 2应用程序中。 I have created two separate DB contexts and different connection strings in appsettings.json . 我在appsettings.json创建了两个单独的数据库上下文和不同的连接字符串。

appsettings.json appsettings.json

"DefaultConnection": "Server=db;Database=DB;User=u;Password=pwd;",
"InventoryCon": "Server=db;Database=DB;User=u;Password=pwd;"

startup: 启动:

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

    services.AddDbContext<InventoryDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("InventoryCon")));

    services.AddMvc();
}

I am specifying default schema in each of the dbContextClasses: Inventory: 我在每个dbContextClasses中指定默认模式:库存:

...protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema("inventory");
}

Customer: 顾客:

...protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema("customer");
}

In Program I am trying to seed both: 在程序中,我试图播种这两种种子:

public static void Main(string[] args)
{
    var host = BuildWebHost(args);

    using (var scope = host.Services.CreateScope())
    {
        var services = scope.ServiceProvider;
        try
        {
            var context = services.GetRequiredService<CustomerDbContext>();
            DbInitializer.Initialize(context);

        }
        catch (Exception ex)
        {
            var logger = services.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "An error occurred while seeding Customer database.");
        }

        try
        {
            var contexti = services.GetRequiredService<InventoryDbContext>();
            DbInitializer.InitInventory(contexti);
        }
        catch (Exception ex)
        {
            var logger = services.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "An error occurred while seeding Inventory database.");
        }
    }

    host.Run();
}

The above works fine if the connections strings are to different databases so I am guessing it has an issue with two connection strings to the same DB. 如果将连接字符串连接到不同的数据库,则上述方法可以很好地工作,因此我猜测两个连接字符串连接到同一数据库存在问题。 Ideally I could separate out these tables into separate schemas so I can better control access for queries. 理想情况下,我可以将这些表分离为单独的模式,以便更好地控制对查询的访问。

Any ideas on how I can separate my tables into separate schemas? 关于如何将表分成单独的架构的任何想法?

EDIT: Adding ERROR: 编辑:添加错误:

info: Microsoft.EntityFrameworkCore.Infrastructure[10403] Entity Framework Core 2.0.1-rtm-125 initialized 'InventoryDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None Microsoft.EntityFrameworkCore.Infrastructure:Information: Entity Framework Core 2.0.1-rtm-125 initialized 'InventoryDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None info: Microsoft.EntityFrameworkCore.Database.Command[20101] Executed DbCommand (32ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE') SELECT 1 ELSE SELECT 0 Microsoft.EntityFrameworkCore.Database.Command:Information: Executed DbCommand (32ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE') SELECT 1 ELSE SELECT 0 'dotnet.exe"' (CoreCLR: clrhost): Loaded 'C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App 信息:Microsoft.EntityFrameworkCore.Infrastructure [10403]实体框架核心2.0.1-rtm-125使用提供程序'Microsoft.EntityFrameworkCore.SqlServer'初始化了'InventoryDbContext',选项为:无Microsoft.EntityFrameworkCore.Infrastructure:Information:实体框架核心2.0。 1-rtm-125使用提供程序'Microsoft.EntityFrameworkCore.SqlServer'初始化了'InventoryDbContext',并具有以下选项:无信息:Microsoft.EntityFrameworkCore.Database.Command [20101]执行的DbCommand(32ms)[Parameters = [],CommandType ='Text' ,CommandTimeout = '30']如果存在(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE ='BASE TABLE')SELECT 1 ELSE SELECT 0 Microsoft.EntityFrameworkCore.Database.Command:Information:已执行DbCommand(32ms)[Parameters = [],如果存在(CommandType =“文本”,CommandTimeout =“ 30”)(选择*从INFORMATION_SCHEMA.TABLES,其中TABLE_TYPE ='BASE TABLE')SELECT 1 ELSE SELECT 0'dotnet.exe“(CoreCLR:clrhost):已加载'C: \\ Program Files \\ dotnet \\ shared \\ Microsoft.NETCore.App \\2.0.4\\System.Diagnostics.StackTrace.dll'. \\ 2.0.4 \\ System.Diagnostics.StackTrace.dll”。 Skipped loading symbols. 跳过的加载符号。 Module is optimized and the debugger option 'Just My Code' is enabled. 模块已优化,调试器选项“ Just My Code”已启用。 'dotnet.exe"' (CoreCLR: clrhost): Loaded 'C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\\2.0.4\\System.Reflection.Metadata.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. fail: Microsoft.EntityFrameworkCore.Database.Command[20102] Failed executing DbCommand (4ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT CASE WHEN EXISTS ( SELECT 1 FROM [inventory].[DUA] AS [d]) THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END System.Data.SqlClient.SqlException (0x80131904): Invalid object name 'inventory.DUA'. “ dotnet.exe”(CoreCLR:clrhost):已加载“ C:\\ Program Files \\ dotnet \\ shared \\ Microsoft.NETCore.App \\ 2.0.4 \\ System.Reflection.Metadata.dll”。跳过了加载符号。模块已优化并且调试器选项“仅我的代码”已启用。失败:Microsoft.EntityFrameworkCore.Database.Command [20102]执行DbCommand失败(4ms)[Parameters = [],CommandType ='Text',CommandTimeout = '30']选择情况存在时(从[清单]中选择1。[DUA] AS [d])然后CAST(1位)ELSE CAST(0位)END System.Data.SqlClient.SqlException(0x80131904):无效的对象名称“库存”。 DUA'。

I noticed the following in the logs when it creates the schema for customer, which never happens for inventory: IF SCHEMA_ID(N'customer') IS NULL EXEC(N'CREATE SCHEMA [customer];'); 我在为客户创建架构时在日志中注意到以下内容,这对于清单来说永远不会发生:IF SCHEMA_ID(N'customer')IS NULL EXEC(N'CREATE SCHEMA [customer];');

I want to say that its complaining about both contexts writing to the same 'default' migrations history table in the database. 我想说的是,它抱怨两个上下文都写入数据库中相同的“默认”迁移历史记录表。

To get around this, you'll need to slightly modify your service configuration so that it specifies different migration tables for each of the contexts you have: 要解决此问题,您需要稍微修改服务配置,以便为您拥有的每个上下文指定不同的迁移表:

services.AddDbContext<CustomerDbContext>(
                options => options.UseSqlServer(
                    this.Configuration.GetConnectionString("DefaultConnection"),
                    sqlServerOptions => sqlServerOptions.MigrationsHistoryTable("Customer")));

services.AddDbContext<InventoryDbContext>(
                options => options.UseSqlServer(
                    this.Configuration.GetConnectionString("DefaultConnection"),
                    sqlServerOptions => sqlServerOptions.MigrationsHistoryTable("Inventory")));

Edit: Fixed the code snippet. 编辑:修复了代码段。

My issue was I was using EF with database.EnsureCreated which only checks if the database is there and if not it creates the DB and the specified schema for that context. 我的问题是我将EF与database.EnsureCreated一起使用,它仅检查数据库是否存在,如果不存在,它将为该上下文创建数据库和指定的架构。 On successive calls it sees the database and does not create the schema. 在后续调用中,它会看到数据库,并且不会创建架构。 The explanation and solution is by rowan miller here . 的解释和解决方案是罗文·米勒在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何处理来自单独 EF Core 架构/上下文的关系? - How to handle relationships from separate EF Core schemas/contexts? 具有多个数据库架构的EF Core迁移 - EF Core Migrations with Multiple DB Schemas 如何使用来自同一ASP.NET Core C#代码的不同数据库(SQL Server,Oracle) - How to use different databases (SQL Server, Oracle) from the same ASP.NET Core C# code EF在相同类型的不同上下文之间切换 - EF Switch between different contexts of same type 在多个不同的带有EF内核的DB环境中,需要访问Connection state - In multiple different DB enviroment with EF core, need to access Connection state 与 Azure SQL 相比,使用 EF Core 生成的 PK 在本地 SQL Server 上是不同的 (ALLOW_ROW_LOCKS) - PK generated with EF Core is different on local SQL Server compared to Azure SQL (ALLOW_ROW_LOCKS) 多重上下文 ef-core - Multiples contexts ef-core EF Core - 多个上下文和事务 - EF Core - Multiple Contexts and Transactions 使用具有 .net 内核的同一组件的不同版本 - Using different versions of the same assembly with .net core .NET Core Automapper 相同类型的不同映射 - .NET Core Automapper different mappings for same types
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM