簡體   English   中英

帶有EF Core的.NET Core 2在同一數據庫(SQL Server)中具有不同架構的不同上下文

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

我想在兩個單獨的架構中將表放在C#ASP.NET Core 2應用程序中。 我在appsettings.json創建了兩個單獨的數據庫上下文和不同的連接字符串。

appsettings.json

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

啟動:

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

我在每個dbContextClasses中指定默認模式:庫存:

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

顧客:

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

在程序中,我試圖播種這兩種種子:

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

如果將連接字符串連接到不同的數據庫,則上述方法可以很好地工作,因此我猜測兩個連接字符串連接到同一數據庫存在問題。 理想情況下,我可以將這些表分離為單獨的模式,以便更好地控制對查詢的訪問。

關於如何將表分成單獨的架構的任何想法?

編輯:添加錯誤:

信息: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”。 跳過的加載符號。 模塊已優化,調試器選項“ Just My Code”已啟用。 “ 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'。

我在為客戶創建架構時在日志中注意到以下內容,這對於清單來說永遠不會發生:IF SCHEMA_ID(N'customer')IS NULL EXEC(N'CREATE SCHEMA [customer];');

我想說的是,它抱怨兩個上下文都寫入數據庫中相同的“默認”遷移歷史記錄表。

要解決此問題,您需要稍微修改服務配置,以便為您擁有的每個上下文指定不同的遷移表:

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

編輯:修復了代碼段。

我的問題是我將EF與database.EnsureCreated一起使用,它僅檢查數據庫是否存在,如果不存在,它將為該上下文創建數據庫和指定的架構。 在后續調用中,它會看到數據庫,並且不會創建架構。 的解釋和解決方案是羅文·米勒在這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM