[英].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.