| | | 1 | | using Microsoft.EntityFrameworkCore; |
| | | 2 | | using OzonDomains; |
| | | 3 | | using OzonDomains.Models; |
| | | 4 | | using OzonDomains.Models.AccessControl; |
| | | 5 | | using OzonDomains.Models.ArmtekEtp; |
| | | 6 | | using OzonDomains.Models.Authorization; |
| | | 7 | | using OzonDomains.Models.MatchedRowSys; |
| | | 8 | | using OzonDomains.Models.OrderCarts; |
| | | 9 | | using OzonDomains.Models.OzonHandover; |
| | | 10 | | using OzonDomains.Models.SupplierStatuses; |
| | | 11 | | using OzonRepositories.Authorization; |
| | | 12 | | using OzonRepositories.Data.Bitrix; |
| | | 13 | | |
| | | 14 | | namespace OzonRepositories.Context |
| | | 15 | | { |
| | | 16 | | public class ApplicationDbContext : DbContext |
| | | 17 | | { |
| | | 18 | | |
| | 6355 | 19 | | public DbSet<Order> Orders { get; set; } |
| | 2383 | 20 | | public DbSet<Product> Products { get; set; } |
| | 2305 | 21 | | public DbSet<Currency> Currencys { get; set; } |
| | 2680 | 22 | | public DbSet<Warehouse> Warehouses { get; set; } |
| | 2319 | 23 | | public DbSet<AppStatus> AppStatuses { get; set; } |
| | 2364 | 24 | | public DbSet<ClientStatus> ClientStatuses { get; set; } |
| | 2443 | 25 | | public DbSet<Supplier> Suppliers { get; set; } |
| | 2455 | 26 | | public DbSet<ApiSupplierSettings> ApiSupplierSettings { get; set; } |
| | 2333 | 27 | | public DbSet<ApiSupplierRequestAuditEntry> ApiSupplierRequestAuditEntries { get; set; } = null!; |
| | 2310 | 28 | | public DbSet<SupplierQuotationRequest> SupplierQuotationRequests { get; set; } = null!; |
| | 2304 | 29 | | public DbSet<SupplierQuotationOffer> SupplierQuotationOffers { get; set; } = null!; |
| | 2439 | 30 | | public DbSet<ArmtekDeliveryAddressMapping> ArmtekDeliveryAddressMappings { get; set; } |
| | 2346 | 31 | | public DbSet<ApiSupplierWarehouse> ApiSupplierWarehouses { get; set; } = null!; |
| | 2327 | 32 | | public DbSet<ArmtekSettlement> ArmtekSettlements { get; set; } = null!; |
| | 2338 | 33 | | public DbSet<ArmtekInvoice> ArmtekInvoices { get; set; } = null!; |
| | 2317 | 34 | | public DbSet<ArmtekInvoiceItem> ArmtekInvoiceItems { get; set; } = null!; |
| | 2322 | 35 | | public DbSet<ArmtekEtpSyncRun> ArmtekEtpSyncRuns { get; set; } = null!; |
| | 2367 | 36 | | public DbSet<FidSupplierLink> FidSupplierLinks { get; set; } = null!; |
| | 2313 | 37 | | public DbSet<FidSupplierLinkSettings> FidSupplierLinkSettings { get; set; } = null!; |
| | 2359 | 38 | | public DbSet<Transaction> Transactions { get; set; } |
| | 2495 | 39 | | public DbSet<OzonClient> OzonClients { get; set; } |
| | 2308 | 40 | | public DbSet<AccessProfile> AccessProfiles { get; set; } |
| | 2304 | 41 | | public DbSet<DataScopeSet> DataScopeSets { get; set; } |
| | 2302 | 42 | | public DbSet<DataScopeSetItem> DataScopeSetItems { get; set; } |
| | 2303 | 43 | | public DbSet<ColumnMapping> ColumnMappings { get; set; } |
| | 2452 | 44 | | public DbSet<Manufacturer> Manufacturers { get; set; } |
| | 2302 | 45 | | public DbSet<OrdersFileMetadata> OrdersFileMetadata { get; set; } |
| | 2302 | 46 | | public DbSet<MatchedRow> MatchedRows { get; set; } |
| | 2302 | 47 | | public DbSet<MatchedResult> MatchedResults { get; set; } |
| | 2302 | 48 | | public DbSet<MatchingColumn> MatchingColumns { get; set; } |
| | 2302 | 49 | | public DbSet<SavedMatchingColumn> SavedMatchingColumns { get; set; } |
| | 2337 | 50 | | public DbSet<FileUploadRecord> FileUploadRecords { get; set; } |
| | 2302 | 51 | | public DbSet<OrderCart> OrderCarts { get; set; } |
| | 2302 | 52 | | public DbSet<OrderItem> OrderItems { get; set; } |
| | 2302 | 53 | | public DbSet<CartStatus> CartStatuses { get; set; } |
| | 2302 | 54 | | public DbSet<ItemStatus> ItemStatuses { get; set; } |
| | 2313 | 55 | | public DbSet<StatusColor> StatusColors { get; set; } |
| | 2302 | 56 | | public DbSet<ExcludedArticle> ExcludedArticles { get; set; } |
| | 2302 | 57 | | public DbSet<ExcelMapping> ExcelMappings { get; set; } |
| | 2302 | 58 | | public DbSet<PriceHistory> PriceHistories { get; set; } |
| | 2414 | 59 | | public virtual DbSet<OrderHistory> OrderHistories { get; set; } |
| | 2425 | 60 | | public DbSet<WarehouseMapping> WarehouseMappings { get; set; } |
| | 2304 | 61 | | public DbSet<Delivery> Deliveries { get; set; } |
| | 2302 | 62 | | public DbSet<DeliveryProvider> DeliveryProviders { get; set; } |
| | 2302 | 63 | | public DbSet<ExcludedBitrixWarehouse> ExcludedBitrixWarehouses { get; set; } |
| | 2345 | 64 | | public DbSet<EtProducer> EtProducers { get; set; } |
| | 2348 | 65 | | public DbSet<OrderArchive> OrderArchives { get; set; } |
| | 2302 | 66 | | public DbSet<OrderPrice> OrderPrices { get; set; } |
| | 2302 | 67 | | public DbSet<OrderOzonPromotionSnapshot> OrderOzonPromotionSnapshots { get; set; } = null!; |
| | 2302 | 68 | | public DbSet<OrderOzonPromotionCondition> OrderOzonPromotionConditions { get; set; } = null!; |
| | 2302 | 69 | | public DbSet<PriceIndexes> PriceIndexes { get; set; } |
| | 2310 | 70 | | public DbSet<OrderExtension> OrderExtensions { get; set; } |
| | 2302 | 71 | | public DbSet<BitrixStockSavedFilter> BitrixStockSavedFilters { get; set; } |
| | 2302 | 72 | | public DbSet<ExpenseType> ExpenseTypes { get; set; } |
| | 2302 | 73 | | public DbSet<OrderExtraExpense> OrderExtraExpenses { get; set; } |
| | | 74 | | |
| | | 75 | | /// <summary>Настройки страницы заказов на AG Grid по пользователю (раскладка, пресеты, последний фильтр).</summ |
| | 2324 | 76 | | public DbSet<OrdersGridUserSetting> OrdersGridUserSettings { get; set; } |
| | | 77 | | |
| | | 78 | | /// <summary>Настройки бокового меню по пользователю (избранное, порядок, свёрнутые группы, pin).</summary> |
| | 2302 | 79 | | public DbSet<UserSidebarSetting> UserSidebarSettings { get; set; } |
| | 2303 | 80 | | public DbSet<StatusTransition> StatusTransitions { get; set; } |
| | 2328 | 81 | | public DbSet<StatusTransitionHistory> StatusTransitionHistory { get; set; } |
| | | 82 | | |
| | | 83 | | /// <summary>Имена/иконки/флаг нового грида по типу транзакции (админка /Studio2/TransactionTypeSettings).</summ |
| | 2367 | 84 | | public DbSet<TransactionTypeSetting> TransactionTypeSettings { get; set; } |
| | 2342 | 85 | | public DbSet<Shipment> Shipments { get; set; } |
| | 2304 | 86 | | public DbSet<OzonChatOrder> OzonChatOrders { get; set; } |
| | 2304 | 87 | | public DbSet<OzonChatResponseStatistic> OzonChatResponseStatistics { get; set; } |
| | 2302 | 88 | | public DbSet<OzonChatResponseTime> OzonChatResponseTimes { get; set; } |
| | 2348 | 89 | | public DbSet<OrderReturn> OrderReturns { get; set; } |
| | 2331 | 90 | | public DbSet<OrderReturnSyncRun> OrderReturnSyncRuns { get; set; } |
| | 2325 | 91 | | public DbSet<OzonHandoverImportBatch> OzonHandoverImportBatches { get; set; } |
| | 2302 | 92 | | public DbSet<OzonHandoverAct> OzonHandoverActs { get; set; } |
| | 2307 | 93 | | public DbSet<OzonHandoverActItem> OzonHandoverActItems { get; set; } |
| | 2303 | 94 | | public DbSet<OzonHandoverActItemPhoto> OzonHandoverActItemPhotos { get; set; } |
| | 2302 | 95 | | public DbSet<OrderShipmentTotals> OrderShipmentTotals { get; set; } |
| | 2305 | 96 | | public DbSet<OrderCalculationSnapshot> OrderCalculationSnapshots { get; set; } |
| | 2381 | 97 | | public DbSet<OrderHistoryOneCPosting> OrderHistoryOneCPostings { get; set; } |
| | 2302 | 98 | | public DbSet<OrderHistoryOneCPostingLink> OrderHistoryOneCPostingLinks { get; set; } |
| | 2302 | 99 | | public DbSet<OneCNomenclatureMap> OneCNomenclatureMaps { get; set; } = null!; |
| | 2308 | 100 | | public DbSet<OneCProducerAlias> OneCProducerAliases { get; set; } = null!; |
| | 2302 | 101 | | public DbSet<InterpartsWarehouseLogin> InterpartsWarehouseLogins { get; set; } |
| | 2302 | 102 | | public DbSet<InterpartsSutCurrency> InterpartsSutCurrencies { get; set; } |
| | 2347 | 103 | | public DbSet<OzonPushNotification> OzonPushNotifications { get; set; } |
| | 5218 | 104 | | public DbSet<OzonPostingCancellation> OzonPostingCancellations { get; set; } = null!; |
| | 2353 | 105 | | public DbSet<OzonPostingCancellationOrder> OzonPostingCancellationOrders { get; set; } = null!; |
| | 2308 | 106 | | public DbSet<EmailRoutingRule> EmailRoutingRules { get; set; } |
| | 2337 | 107 | | public DbSet<EmailMessageInbox> EmailMessageInboxes { get; set; } |
| | 2316 | 108 | | public DbSet<EmailAttachmentInbox> EmailAttachmentInboxes { get; set; } |
| | 2304 | 109 | | public DbSet<EmailAttachmentProcessingResult> EmailAttachmentProcessingResults { get; set; } |
| | 2320 | 110 | | public DbSet<EmailRoutingJobExecution> EmailRoutingJobExecutions { get; set; } |
| | 2382 | 111 | | public DbSet<TransactionTimeTrackingSession> TransactionTimeTrackingSessions { get; set; } |
| | 2333 | 112 | | public DbSet<TransactionTimeTrackingResult> TransactionTimeTrackingResults { get; set; } |
| | 2363 | 113 | | public DbSet<WarehouseStockSnapshot> WarehouseStockSnapshots { get; set; } |
| | 2337 | 114 | | public DbSet<WarehouseStockSyncRun> WarehouseStockSyncRuns { get; set; } |
| | | 115 | | |
| | | 116 | | // Background Jobs System |
| | 2333 | 117 | | public DbSet<BackgroundJobSchedule> BackgroundJobSchedules { get; set; } |
| | 2346 | 118 | | public DbSet<BackgroundJobExecution> BackgroundJobExecutions { get; set; } |
| | 2302 | 119 | | public DbSet<BackgroundJobStep> BackgroundJobSteps { get; set; } |
| | 2302 | 120 | | public DbSet<BackgroundReportLoad> BackgroundReportLoads { get; set; } |
| | 2302 | 121 | | public DbSet<BackgroundOrderMatch> BackgroundOrderMatches { get; set; } |
| | 2313 | 122 | | public DbSet<BackgroundTransactionResult> BackgroundTransactionResults { get; set; } |
| | | 123 | | |
| | 2313 | 124 | | public DbSet<OrderSearchSyncState> OrderSearchSyncStates { get; set; } |
| | 2333 | 125 | | public DbSet<OrderControlRule> OrderControlRules { get; set; } = null!; |
| | 2706 | 126 | | public DbSet<OrderControlTask> OrderControlTasks { get; set; } = null!; |
| | 2916 | 127 | | public DbSet<OrderControlTaskEvent> OrderControlTaskEvents { get; set; } = null!; |
| | 2319 | 128 | | public DbSet<OrderControlSettings> OrderControlSettings { get; set; } = null!; |
| | 2302 | 129 | | public DbSet<OrderControlExecution> OrderControlExecutions { get; set; } = null!; |
| | 2417 | 130 | | public DbSet<SystemAlertIncident> SystemAlertIncidents { get; set; } = null!; |
| | 2353 | 131 | | public DbSet<SystemMonitoringSignal> SystemMonitoringSignals { get; set; } = null!; |
| | 2354 | 132 | | public DbSet<ArmtekCartItem> ArmtekCartItems { get; set; } = null!; |
| | 2335 | 133 | | public DbSet<ArmtekOrder> ArmtekOrders { get; set; } = null!; |
| | 2403 | 134 | | public DbSet<ArmtekOrderItem> ArmtekOrderItems { get; set; } = null!; |
| | 2309 | 135 | | public DbSet<MlAutoCartItem> MlAutoCartItems { get; set; } = null!; |
| | 2319 | 136 | | public DbSet<MlAutoOrder> MlAutoOrders { get; set; } = null!; |
| | 2404 | 137 | | public DbSet<MlAutoRuCartItem> MlAutoRuCartItems { get; set; } = null!; |
| | 2355 | 138 | | public DbSet<MlAutoRuOrder> MlAutoRuOrders { get; set; } = null!; |
| | 2339 | 139 | | public DbSet<MlAutoOrderItem> MlAutoOrderItems { get; set; } = null!; |
| | 2343 | 140 | | public DbSet<MlAutoDeliveryAddressMapping> MlAutoDeliveryAddressMappings { get; set; } = null!; |
| | 2346 | 141 | | public DbSet<MlAutoRuDeliveryAddressMapping> MlAutoRuDeliveryAddressMappings { get; set; } = null!; |
| | 2335 | 142 | | public DbSet<ForumAutoCartItem> ForumAutoCartItems { get; set; } = null!; |
| | 2324 | 143 | | public DbSet<ForumAutoOrder> ForumAutoOrders { get; set; } = null!; |
| | 2314 | 144 | | public DbSet<ForumAutoOrderItem> ForumAutoOrderItems { get; set; } = null!; |
| | 2339 | 145 | | public DbSet<FavoritPartsCartItem> FavoritPartsCartItems { get; set; } = null!; |
| | 2332 | 146 | | public DbSet<FavoritPartsOrder> FavoritPartsOrders { get; set; } = null!; |
| | 2329 | 147 | | public DbSet<FavoritPartsOrderItem> FavoritPartsOrderItems { get; set; } = null!; |
| | 2441 | 148 | | public DbSet<ProfitLigaCartItem> ProfitLigaCartItems { get; set; } = null!; |
| | 2357 | 149 | | public DbSet<ProfitLigaOrder> ProfitLigaOrders { get; set; } = null!; |
| | 2308 | 150 | | public DbSet<ProfitLigaOrderItem> ProfitLigaOrderItems { get; set; } = null!; |
| | 2414 | 151 | | public DbSet<ProfitLigaPointMapping> ProfitLigaPointMappings { get; set; } = null!; |
| | 2414 | 152 | | public DbSet<NikeiCartItem> NikeiCartItems { get; set; } = null!; |
| | 2332 | 153 | | public DbSet<MikadoCartItem> MikadoCartItems { get; set; } = null!; |
| | 2453 | 154 | | public DbSet<ZZapCartItem> ZZapCartItems { get; set; } = null!; |
| | 2396 | 155 | | public DbSet<MoskvorechieIstraCartItem> MoskvorechieIstraCartItems { get; set; } = null!; |
| | 2379 | 156 | | public DbSet<MoskvorechieIstraOrder> MoskvorechieIstraOrders { get; set; } = null!; |
| | 2320 | 157 | | public DbSet<MoskvorechieIstraOrderItem> MoskvorechieIstraOrderItems { get; set; } = null!; |
| | 2370 | 158 | | public DbSet<MotexCartItem> MotexCartItems { get; set; } = null!; |
| | 2329 | 159 | | public DbSet<MotexOrder> MotexOrders { get; set; } = null!; |
| | 2305 | 160 | | public DbSet<MotexOrderItem> MotexOrderItems { get; set; } = null!; |
| | 2370 | 161 | | public DbSet<ShateMCartItem> ShateMCartItems { get; set; } = null!; |
| | 2315 | 162 | | public DbSet<ShateMOrder> ShateMOrders { get; set; } = null!; |
| | 2302 | 163 | | public DbSet<ShateMOrderItem> ShateMOrderItems { get; set; } = null!; |
| | 2341 | 164 | | public DbSet<BergCartItem> BergCartItems { get; set; } = null!; |
| | 2329 | 165 | | public DbSet<BergOrder> BergOrders { get; set; } = null!; |
| | 2348 | 166 | | public DbSet<BergOrderItem> BergOrderItems { get; set; } = null!; |
| | 2354 | 167 | | public DbSet<BergDeliveryAddressMapping> BergDeliveryAddressMappings { get; set; } = null!; |
| | 2621 | 168 | | public DbSet<SupplierStatus> SupplierStatuses { get; set; } = null!; |
| | 2932 | 169 | | public DbSet<OrderSupplierState> OrderSupplierStates { get; set; } = null!; |
| | 2371 | 170 | | public DbSet<OrderSupplierStateHistory> OrderSupplierStateHistory { get; set; } = null!; |
| | 2476 | 171 | | public DbSet<SupplierOrderIntent> SupplierOrderIntents { get; set; } = null!; |
| | | 172 | | |
| | 2316 | 173 | | public DbSet<BitrixStockClearExecution> BitrixStockClearExecutions { get; set; } |
| | 2302 | 174 | | public DbSet<BitrixStockClearItem> BitrixStockClearItems { get; set; } |
| | 2302 | 175 | | public DbSet<BitrixStockArchiveExecution> BitrixStockArchiveExecutions { get; set; } |
| | 2302 | 176 | | public DbSet<BitrixStockArchiveItem> BitrixStockArchiveItems { get; set; } |
| | 2302 | 177 | | public DbSet<BitrixStockUnarchiveExecution> BitrixStockUnarchiveExecutions { get; set; } |
| | 2302 | 178 | | public DbSet<BitrixStockUnarchiveItem> BitrixStockUnarchiveItems { get; set; } |
| | 2317 | 179 | | public DbSet<BitrixStockPushExecution> BitrixStockPushExecutions { get; set; } |
| | 2510 | 180 | | public DbSet<BitrixStockPushItem> BitrixStockPushItems { get; set; } |
| | 2311 | 181 | | public DbSet<BitrixStockAutoSchedule> BitrixStockAutoSchedules { get; set; } |
| | 2310 | 182 | | public DbSet<BitrixStockAutoScheduleRun> BitrixStockAutoScheduleRuns { get; set; } |
| | | 183 | | |
| | | 184 | | // Статистика фидов |
| | 2302 | 185 | | public DbSet<FidStatSnapshot> FidStatSnapshots { get; set; } |
| | 2302 | 186 | | public DbSet<FidStatItem> FidStatItems { get; set; } |
| | | 187 | | |
| | | 188 | | // Новая система авторизации (Authorization) |
| | 2367 | 189 | | public DbSet<AppPage> AppPages { get; set; } = null!; |
| | 2326 | 190 | | public DbSet<AppField> AppFields { get; set; } = null!; |
| | 2309 | 191 | | public DbSet<DataScope> DataScopes { get; set; } = null!; |
| | 2399 | 192 | | public DbSet<AppRole> AppRoles { get; set; } = null!; |
| | 2335 | 193 | | public DbSet<RolePagePermission> RolePagePermissions { get; set; } = null!; |
| | 2337 | 194 | | public DbSet<RoleFieldPermission> RoleFieldPermissions { get; set; } = null!; |
| | 2334 | 195 | | public DbSet<RoleDataScope> RoleDataScopes { get; set; } = null!; |
| | 2689 | 196 | | public DbSet<UserAppRole> UserAppRoles { get; set; } = null!; |
| | 2330 | 197 | | public DbSet<UserPageOverride> UserPageOverrides { get; set; } = null!; |
| | 2330 | 198 | | public DbSet<UserFieldOverride> UserFieldOverrides { get; set; } = null!; |
| | 2342 | 199 | | public DbSet<UserDataScope> UserDataScopes { get; set; } = null!; |
| | 2302 | 200 | | public DbSet<AuditLogEntry> AuditLogEntries { get; set; } = null!; |
| | 2307 | 201 | | public DbSet<LabelPrintLog> LabelPrintLogs { get; set; } = null!; |
| | | 202 | | |
| | | 203 | | // Листы подбора FBS |
| | 2302 | 204 | | public DbSet<AssemblyListRun> AssemblyListRuns { get; set; } = null!; |
| | 2302 | 205 | | public DbSet<AssemblyListRunItem> AssemblyListRunItems { get; set; } = null!; |
| | 2302 | 206 | | public DbSet<AssemblyListAccessKey> AssemblyListAccessKeys { get; set; } = null!; |
| | 2540 | 207 | | public DbSet<OzonDomains.Models.Partners.Partner> Partners { get; set; } = null!; |
| | 2373 | 208 | | public DbSet<OzonDomains.Models.Partners.PartnerRule> PartnerRules { get; set; } = null!; |
| | 2302 | 209 | | public DbSet<OzonDomains.Models.Partners.PartnerRuleCondition> PartnerRuleConditions { get; set; } = null!; |
| | 2318 | 210 | | public DbSet<OzonDomains.Models.Partners.PartnerPermission> PartnerPermissions { get; set; } = null!; |
| | 2399 | 211 | | public DbSet<OzonDomains.Models.Partners.PartnerAuditLog> PartnerAuditLogs { get; set; } = null!; |
| | 2387 | 212 | | public DbSet<OzonDomains.Models.Partners.PartnerLoginCode> PartnerLoginCodes { get; set; } = null!; |
| | | 213 | | |
| | 0 | 214 | | public ApplicationDbContext() |
| | | 215 | | { |
| | 0 | 216 | | } |
| | | 217 | | |
| | | 218 | | public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) |
| | 2302 | 219 | | : base(options) |
| | | 220 | | { |
| | 2302 | 221 | | } |
| | | 222 | | |
| | | 223 | | private static void ConfigurePartnerOffice(ModelBuilder modelBuilder) |
| | | 224 | | { |
| | 12 | 225 | | modelBuilder.Entity<OzonDomains.Models.Partners.Partner>(e => |
| | 12 | 226 | | { |
| | 12 | 227 | | e.HasIndex(x => x.Login).IsUnique(); |
| | 12 | 228 | | e.HasIndex(x => x.GoogleEmail); |
| | 12 | 229 | | e.HasIndex(x => x.Email).IsUnique(); |
| | 12 | 230 | | e.HasMany(x => x.LoginCodes).WithOne(x => x.Partner).HasForeignKey(x => x.PartnerId).OnDelete(DeleteBeha |
| | 12 | 231 | | e.HasMany(x => x.Rules).WithOne(x => x.Partner).HasForeignKey(x => x.PartnerId).OnDelete(DeleteBehavior. |
| | 12 | 232 | | e.HasMany(x => x.Permissions).WithOne(x => x.Partner).HasForeignKey(x => x.PartnerId).OnDelete(DeleteBeh |
| | 24 | 233 | | }); |
| | 12 | 234 | | modelBuilder.Entity<OzonDomains.Models.Partners.PartnerRule>(e => |
| | 24 | 235 | | e.HasMany(x => x.Conditions).WithOne(x => x.Rule).HasForeignKey(x => x.RuleId).OnDelete(DeleteBehavior.C |
| | 12 | 236 | | modelBuilder.Entity<OzonDomains.Models.Partners.PartnerPermission>(e => |
| | 24 | 237 | | e.HasIndex(x => new { x.PartnerId, x.Code }).IsUnique()); |
| | 12 | 238 | | modelBuilder.Entity<OzonDomains.Models.Partners.PartnerLoginCode>(e => |
| | 24 | 239 | | e.HasIndex(x => new { x.PartnerId, x.CreatedAtUtc })); |
| | 12 | 240 | | modelBuilder.Entity<OzonDomains.Models.Partners.PartnerAuditLog>(e => |
| | 12 | 241 | | { |
| | 12 | 242 | | e.HasIndex(x => x.OccurredAtUtc); |
| | 12 | 243 | | e.HasIndex(x => new { x.PartnerId, x.OccurredAtUtc }); |
| | 24 | 244 | | }); |
| | 12 | 245 | | } |
| | | 246 | | |
| | | 247 | | protected override void OnModelCreating(ModelBuilder modelBuilder) |
| | | 248 | | { |
| | 12 | 249 | | ConfigurePartnerOffice(modelBuilder); |
| | 12 | 250 | | modelBuilder.Entity<Shipment>(e => |
| | 12 | 251 | | { |
| | 12 | 252 | | e.HasIndex(x => x.ShipmentNumber) |
| | 12 | 253 | | .IsUnique() |
| | 12 | 254 | | .HasDatabaseName("UX_Shipments_ShipmentNumber"); |
| | 24 | 255 | | }); |
| | 12 | 256 | | modelBuilder.Entity<SystemAlertIncident>(e => |
| | 12 | 257 | | { |
| | 12 | 258 | | e.HasIndex(x => new { x.Key, x.IsActive }); |
| | 12 | 259 | | e.HasIndex(x => x.LastObservedAtUtc); |
| | 24 | 260 | | }); |
| | 24 | 261 | | modelBuilder.Entity<SystemMonitoringSignal>(e => e.HasIndex(x => new { x.SourceKey, x.OccurredAtUtc })); |
| | 12 | 262 | | modelBuilder.Entity<LabelPrintLog>(e => |
| | 12 | 263 | | { |
| | 12 | 264 | | e.HasIndex(x => new { x.FileName, x.OccurredAtUtc }); |
| | 12 | 265 | | e.HasIndex(x => new { x.OrderId, x.OccurredAtUtc }); |
| | 24 | 266 | | }); |
| | 12 | 267 | | modelBuilder.Entity<ApiSupplierSettings>() |
| | 12 | 268 | | .HasIndex(x => x.ProviderKey) |
| | 12 | 269 | | .IsUnique(); |
| | 12 | 270 | | modelBuilder.Entity<ApiSupplierSettings>() |
| | 12 | 271 | | .Property(x => x.PriceMultiplier) |
| | 12 | 272 | | .HasPrecision(10, 4); |
| | 12 | 273 | | modelBuilder.Entity<ApiSupplierSettings>() |
| | 12 | 274 | | .HasOne(x => x.Supplier) |
| | 12 | 275 | | .WithMany() |
| | 12 | 276 | | .HasForeignKey(x => x.SupplierId) |
| | 12 | 277 | | .OnDelete(DeleteBehavior.SetNull); |
| | 12 | 278 | | modelBuilder.Entity<ApiSupplierRequestAuditEntry>(e => |
| | 12 | 279 | | { |
| | 12 | 280 | | e.ToTable("ApiSupplierRequestAudit"); |
| | 12 | 281 | | e.HasIndex(x => new { x.ProviderKey, x.OccurredAtUtc }); |
| | 12 | 282 | | e.HasIndex(x => new { x.IsSuccess, x.OccurredAtUtc }); |
| | 12 | 283 | | e.Property(x => x.Request).HasColumnType("longtext"); |
| | 12 | 284 | | e.Property(x => x.Response).HasColumnType("longtext"); |
| | 24 | 285 | | }); |
| | 12 | 286 | | modelBuilder.Entity<SupplierQuotationRequest>() |
| | 12 | 287 | | .HasIndex(x => new { x.ProductId, x.RequestedAtUtc }); |
| | 12 | 288 | | modelBuilder.Entity<SupplierQuotationRequest>() |
| | 12 | 289 | | .HasIndex(x => new { x.OrderId, x.RequestedAtUtc }); |
| | 12 | 290 | | modelBuilder.Entity<SupplierQuotationRequest>() |
| | 12 | 291 | | .HasOne(x => x.Product).WithMany().HasForeignKey(x => x.ProductId).OnDelete(DeleteBehavior.Restrict); |
| | 12 | 292 | | modelBuilder.Entity<SupplierQuotationRequest>() |
| | 12 | 293 | | .HasOne(x => x.Order).WithMany().HasForeignKey(x => x.OrderId).OnDelete(DeleteBehavior.Restrict); |
| | 12 | 294 | | modelBuilder.Entity<SupplierQuotationRequest>() |
| | 12 | 295 | | .HasOne(x => x.Supplier).WithMany().HasForeignKey(x => x.SupplierId).OnDelete(DeleteBehavior.SetNull); |
| | 12 | 296 | | modelBuilder.Entity<SupplierQuotationOffer>() |
| | 12 | 297 | | .HasIndex(x => x.RequestId); |
| | 12 | 298 | | modelBuilder.Entity<SupplierQuotationOffer>() |
| | 12 | 299 | | .HasOne(x => x.Request).WithMany(x => x.Offers).HasForeignKey(x => x.RequestId).OnDelete(DeleteBehavior. |
| | 12 | 300 | | modelBuilder.Entity<ArmtekDeliveryAddressMapping>() |
| | 12 | 301 | | .HasIndex(x => new { x.ProviderKey, x.ShipmentWarehouseId }) |
| | 12 | 302 | | .IsUnique(); |
| | 12 | 303 | | modelBuilder.Entity<ArmtekDeliveryAddressMapping>() |
| | 12 | 304 | | .HasOne(x => x.ShipmentWarehouse) |
| | 12 | 305 | | .WithMany() |
| | 12 | 306 | | .HasForeignKey(x => x.ShipmentWarehouseId) |
| | 12 | 307 | | .OnDelete(DeleteBehavior.Restrict); |
| | 12 | 308 | | modelBuilder.Entity<ApiSupplierWarehouse>() |
| | 12 | 309 | | .HasIndex(x => new { x.ProviderKey, x.WarehouseId }) |
| | 12 | 310 | | .IsUnique(); |
| | 12 | 311 | | modelBuilder.Entity<ApiSupplierWarehouse>() |
| | 12 | 312 | | .HasOne(x => x.Warehouse) |
| | 12 | 313 | | .WithMany() |
| | 12 | 314 | | .HasForeignKey(x => x.WarehouseId) |
| | 12 | 315 | | .OnDelete(DeleteBehavior.Cascade); |
| | 12 | 316 | | modelBuilder.Entity<ArmtekSettlement>(e => |
| | 12 | 317 | | { |
| | 12 | 318 | | e.HasIndex(x => new { x.Kunnr, x.Vbeln }).IsUnique(); |
| | 12 | 319 | | e.HasIndex(x => x.DocDate); |
| | 24 | 320 | | }); |
| | 12 | 321 | | modelBuilder.Entity<ArmtekInvoice>(e => |
| | 12 | 322 | | { |
| | 12 | 323 | | e.HasIndex(x => new { x.Kunnr, x.Vbeln }).IsUnique(); |
| | 12 | 324 | | e.HasMany(x => x.Items).WithOne(x => x.Invoice).HasForeignKey(x => x.InvoiceId).OnDelete(DeleteBehavior. |
| | 24 | 325 | | }); |
| | 12 | 326 | | modelBuilder.Entity<ArmtekInvoiceItem>().HasIndex(x => x.OrderNumber); |
| | 12 | 327 | | modelBuilder.Entity<ArmtekEtpSyncRun>().HasIndex(x => new { x.Success, x.StartedAtUtc }); |
| | 12 | 328 | | modelBuilder.Entity<FidSupplierLink>().HasIndex(x => x.FidSupplierName).IsUnique(); |
| | 12 | 329 | | modelBuilder.Entity<FidSupplierLink>().HasIndex(x => x.ProviderKey); |
| | | 330 | | // Одна строка настроек: Id задаётся приложением, автоинкремент не нужен. |
| | 12 | 331 | | modelBuilder.Entity<FidSupplierLinkSettings>().Property(x => x.Id).ValueGeneratedNever(); |
| | 12 | 332 | | modelBuilder.Entity<MlAutoDeliveryAddressMapping>() |
| | 12 | 333 | | .HasIndex(x => x.ShipmentWarehouseId).IsUnique(); |
| | 12 | 334 | | modelBuilder.Entity<MlAutoDeliveryAddressMapping>() |
| | 12 | 335 | | .HasOne(x => x.ShipmentWarehouse).WithMany().HasForeignKey(x => x.ShipmentWarehouseId) |
| | 12 | 336 | | .OnDelete(DeleteBehavior.Restrict); |
| | 12 | 337 | | modelBuilder.Entity<MlAutoRuDeliveryAddressMapping>() |
| | 12 | 338 | | .HasIndex(x => x.ShipmentWarehouseId).IsUnique(); |
| | 12 | 339 | | modelBuilder.Entity<MlAutoRuDeliveryAddressMapping>() |
| | 12 | 340 | | .HasOne(x => x.ShipmentWarehouse).WithMany().HasForeignKey(x => x.ShipmentWarehouseId) |
| | 12 | 341 | | .OnDelete(DeleteBehavior.Restrict); |
| | | 342 | | |
| | 12 | 343 | | modelBuilder |
| | 12 | 344 | | .Entity<Order>() |
| | 24 | 345 | | .ToTable("Orders", t => t.IsTemporal()); |
| | 12 | 346 | | modelBuilder.Entity<Order>() |
| | 12 | 347 | | .HasIndex(o => o.Key); |
| | | 348 | | // Поиск заказа по штрихкоду ScanIt с этикетки (поле «Номер заказа» в гриде). |
| | 12 | 349 | | modelBuilder.Entity<Order>() |
| | 12 | 350 | | .HasIndex(o => o.Scanit) |
| | 12 | 351 | | .HasDatabaseName("IX_Orders_Scanit"); |
| | | 352 | | // Дельта-опрос грида заказов и инкрементальный синк ES: WHERE UpdatedAt > @since. |
| | 12 | 353 | | modelBuilder.Entity<Order>() |
| | 12 | 354 | | .HasIndex(o => o.UpdatedAt) |
| | 12 | 355 | | .HasDatabaseName("IX_Orders_UpdatedAt"); |
| | | 356 | | // Загрузка заказов (OrdersDataServices): WHERE Article = @article на каждый заказ; без индекса — полный ска |
| | 12 | 357 | | modelBuilder.Entity<Order>() |
| | 12 | 358 | | .HasIndex(o => o.Article) |
| | 12 | 359 | | .HasDatabaseName("IX_Orders_Article"); |
| | 12 | 360 | | modelBuilder.Entity<OzonPostingCancellation>() |
| | 12 | 361 | | .HasIndex(x => x.EventFingerprint) |
| | 12 | 362 | | .IsUnique(); |
| | 12 | 363 | | modelBuilder.Entity<OzonPostingCancellation>() |
| | 12 | 364 | | .HasIndex(x => new { x.OzonClientId, x.PostingNumber }); |
| | 12 | 365 | | modelBuilder.Entity<OzonPostingCancellation>() |
| | 12 | 366 | | .HasOne(x => x.OzonClient) |
| | 12 | 367 | | .WithMany() |
| | 12 | 368 | | .HasForeignKey(x => x.OzonClientId) |
| | 12 | 369 | | .OnDelete(DeleteBehavior.Restrict); |
| | 12 | 370 | | modelBuilder.Entity<OzonPostingCancellationOrder>() |
| | 12 | 371 | | .HasKey(x => new { x.CancellationId, x.OrderId }); |
| | 12 | 372 | | modelBuilder.Entity<OzonPostingCancellationOrder>() |
| | 12 | 373 | | .HasIndex(x => x.OrderId); |
| | 12 | 374 | | modelBuilder.Entity<OzonPostingCancellationOrder>() |
| | 12 | 375 | | .HasOne(x => x.Cancellation) |
| | 12 | 376 | | .WithMany(x => x.OrderLinks) |
| | 12 | 377 | | .HasForeignKey(x => x.CancellationId) |
| | 12 | 378 | | .OnDelete(DeleteBehavior.Cascade); |
| | 12 | 379 | | modelBuilder.Entity<OzonPostingCancellationOrder>() |
| | 12 | 380 | | .HasOne(x => x.Order) |
| | 12 | 381 | | .WithMany() |
| | 12 | 382 | | .HasForeignKey(x => x.OrderId) |
| | 12 | 383 | | .OnDelete(DeleteBehavior.Cascade); |
| | 12 | 384 | | modelBuilder.Entity<Order>() |
| | 12 | 385 | | .HasOne(o => o.EtProducer) |
| | 12 | 386 | | .WithMany() |
| | 12 | 387 | | .HasForeignKey(o => o.EtProducerId) |
| | 12 | 388 | | .OnDelete(DeleteBehavior.Restrict); |
| | | 389 | | |
| | 12 | 390 | | modelBuilder.Entity<OrderArchive>() |
| | 12 | 391 | | .HasOne(oa => oa.Order) |
| | 12 | 392 | | .WithOne(o => o.OrderArchive) |
| | 12 | 393 | | .HasForeignKey<OrderArchive>(oa => oa.OrderId) |
| | 12 | 394 | | .OnDelete(DeleteBehavior.Cascade); |
| | | 395 | | |
| | 12 | 396 | | modelBuilder.Entity<OrderArchive>() |
| | 12 | 397 | | .HasIndex(oa => oa.OrderId) |
| | 12 | 398 | | .IsUnique(); |
| | | 399 | | |
| | 12 | 400 | | modelBuilder.Entity<OrderArchive>() |
| | 12 | 401 | | .HasIndex(oa => oa.ArchivedAt); |
| | | 402 | | |
| | | 403 | | // На один заказ приходится несколько строк цен: в боевой БД 16 234 заказа |
| | | 404 | | // имеют больше одной записи в OrderPrices. Индекс здесь неуникальный — |
| | | 405 | | // раньше модель объявляла его уникальным и физически не разворачивалась. |
| | 12 | 406 | | modelBuilder.Entity<OrderPrice>() |
| | 12 | 407 | | .HasIndex(op => op.OrderId); |
| | | 408 | | |
| | 12 | 409 | | modelBuilder.Entity<OrderOzonPromotionSnapshot>(entity => |
| | 12 | 410 | | { |
| | 12 | 411 | | entity.HasIndex(x => x.OrderId).IsUnique(); |
| | 12 | 412 | | entity.HasIndex(x => new { x.HasAnyPromotion, x.CapturedAt }); |
| | 12 | 413 | | entity.HasIndex(x => new { x.OzonClientId, x.OzonProductId }); |
| | 12 | 414 | | entity.HasOne(x => x.Order) |
| | 12 | 415 | | .WithOne(x => x.OzonPromotionSnapshot) |
| | 12 | 416 | | .HasForeignKey<OrderOzonPromotionSnapshot>(x => x.OrderId) |
| | 12 | 417 | | .OnDelete(DeleteBehavior.Cascade); |
| | 24 | 418 | | }); |
| | | 419 | | |
| | 12 | 420 | | modelBuilder.Entity<OrderOzonPromotionCondition>(entity => |
| | 12 | 421 | | { |
| | 12 | 422 | | entity.HasIndex(x => new { x.SnapshotId, x.SourceType }); |
| | 12 | 423 | | entity.HasIndex(x => new { x.SourceType, x.ExternalActionId }); |
| | 12 | 424 | | entity.HasOne(x => x.Snapshot) |
| | 12 | 425 | | .WithMany(x => x.Conditions) |
| | 12 | 426 | | .HasForeignKey(x => x.SnapshotId) |
| | 12 | 427 | | .OnDelete(DeleteBehavior.Cascade); |
| | 24 | 428 | | }); |
| | | 429 | | |
| | | 430 | | // Неуникальный — как в боевой БД. Дублей сейчас нет, но уникальности |
| | | 431 | | // ни код, ни схема не гарантировали. |
| | 12 | 432 | | modelBuilder.Entity<PriceIndexes>() |
| | 12 | 433 | | .HasIndex(pi => pi.OrderPriceId); |
| | | 434 | | |
| | | 435 | | // Первичный ключ — суррогатный Id (как в БД), а не пара OrderId+Key. |
| | | 436 | | // С составным ключом EF считал автоинкрементный Id обычным свойством |
| | | 437 | | // и на любой вставке через контекст подставил бы Id = 0. |
| | 12 | 438 | | modelBuilder.Entity<OrderExtension>(entity => |
| | 12 | 439 | | { |
| | 12 | 440 | | entity.HasKey(e => e.Id); |
| | 12 | 441 | | entity.HasIndex(e => new { e.OrderId, e.Key }).IsUnique(); |
| | 24 | 442 | | }); |
| | | 443 | | |
| | 12 | 444 | | modelBuilder.Entity<Order>() |
| | 12 | 445 | | .HasMany(o => o.OrderExtensions) |
| | 12 | 446 | | .WithOne(e => e.Order) |
| | 12 | 447 | | .HasForeignKey(e => e.OrderId) |
| | 12 | 448 | | .OnDelete(DeleteBehavior.Cascade); |
| | | 449 | | |
| | | 450 | | // Примечание: Уникальность заказов обеспечивается на уровне приложения в методе AddOrders |
| | | 451 | | // Логика уникальности: |
| | | 452 | | // - Для YANDEX: по полю Key (где Key не null) |
| | | 453 | | // - Для остальных: по комбинации Article + TrimShipmentNumber(ShipmentNumber) |
| | | 454 | | // Уникальный индекс на уровне БД не создается, так как логика требует TrimShipmentNumber, |
| | | 455 | | // что невозможно реализовать на уровне БД без вычисляемых колонок. |
| | | 456 | | |
| | | 457 | | // Self-referencing foreign key для Product (кросскод/замена артикула) |
| | 12 | 458 | | modelBuilder.Entity<Product>() |
| | 12 | 459 | | .HasOne(p => p.ReplacementProduct) |
| | 12 | 460 | | .WithMany(p => p.ReplacedProducts) |
| | 12 | 461 | | .HasForeignKey(p => p.ReplacementProductId) |
| | 12 | 462 | | .OnDelete(DeleteBehavior.Restrict); |
| | | 463 | | |
| | | 464 | | // StatusTransition: переходы между статусами |
| | 12 | 465 | | modelBuilder.Entity<StatusTransition>(entity => |
| | 12 | 466 | | { |
| | 24 | 467 | | entity.ToTable(t => t.HasCheckConstraint( |
| | 24 | 468 | | "CHK_StatusTransitions_DifferentStatuses", |
| | 24 | 469 | | "`FromStatusId` <> `ToStatusId`")); |
| | 12 | 470 | | entity.HasOne(st => st.FromStatus) |
| | 12 | 471 | | .WithMany() |
| | 12 | 472 | | .HasForeignKey(st => st.FromStatusId) |
| | 12 | 473 | | .OnDelete(DeleteBehavior.Restrict); |
| | 12 | 474 | | entity.HasOne(st => st.ToStatus) |
| | 12 | 475 | | .WithMany() |
| | 12 | 476 | | .HasForeignKey(st => st.ToStatusId) |
| | 12 | 477 | | .OnDelete(DeleteBehavior.Restrict); |
| | 12 | 478 | | entity.HasIndex(st => new { st.FromStatusId, st.ToStatusId, st.TransactionType }) |
| | 12 | 479 | | .IsUnique(); |
| | 24 | 480 | | }); |
| | | 481 | | |
| | | 482 | | // StatusTransitionHistory (StatusTransition опционален для ручного изменения статуса) |
| | 12 | 483 | | modelBuilder.Entity<StatusTransitionHistory>() |
| | 12 | 484 | | .HasOne(h => h.StatusTransition) |
| | 12 | 485 | | .WithMany() |
| | 12 | 486 | | .HasForeignKey(h => h.StatusTransitionId) |
| | 12 | 487 | | .IsRequired(false) |
| | 12 | 488 | | .OnDelete(DeleteBehavior.Restrict); |
| | 12 | 489 | | modelBuilder.Entity<StatusTransitionHistory>() |
| | 12 | 490 | | .HasOne(h => h.FromStatus) |
| | 12 | 491 | | .WithMany() |
| | 12 | 492 | | .HasForeignKey(h => h.FromStatusId) |
| | 12 | 493 | | .OnDelete(DeleteBehavior.Restrict); |
| | 12 | 494 | | modelBuilder.Entity<StatusTransitionHistory>() |
| | 12 | 495 | | .HasOne(h => h.ToStatus) |
| | 12 | 496 | | .WithMany() |
| | 12 | 497 | | .HasForeignKey(h => h.ToStatusId) |
| | 12 | 498 | | .OnDelete(DeleteBehavior.Restrict); |
| | 12 | 499 | | modelBuilder.Entity<StatusTransitionHistory>() |
| | 12 | 500 | | .HasIndex(h => new { h.EntityType, h.EntityId }); |
| | 12 | 501 | | modelBuilder.Entity<StatusTransitionHistory>() |
| | 12 | 502 | | .HasIndex(h => h.PerformedAt); |
| | | 503 | | |
| | | 504 | | // OzonChatOrder: связь чатов и заказов |
| | 12 | 505 | | modelBuilder.Entity<OzonChatOrder>() |
| | 12 | 506 | | .HasIndex(x => x.ChatId); |
| | 12 | 507 | | modelBuilder.Entity<OzonChatOrder>() |
| | 12 | 508 | | .HasIndex(x => x.OrderId); |
| | 12 | 509 | | modelBuilder.Entity<OzonChatOrder>() |
| | 12 | 510 | | .HasIndex(x => x.ClientId); |
| | 12 | 511 | | modelBuilder.Entity<OzonChatOrder>() |
| | 12 | 512 | | .HasIndex(x => x.PostingNumber); |
| | | 513 | | // Неуникальный: в боевой базе 54 пары (ChatId, OrderId) задвоены. |
| | | 514 | | // Уникальный индекс здесь физически не создать, пока дубли не вычищены. |
| | 12 | 515 | | modelBuilder.Entity<OzonChatOrder>() |
| | 12 | 516 | | .HasIndex(x => new { x.ChatId, x.OrderId }); |
| | 12 | 517 | | modelBuilder.Entity<OzonChatOrder>() |
| | 12 | 518 | | .HasIndex(x => new { x.IsActive, x.ClientId }); |
| | 12 | 519 | | modelBuilder.Entity<OzonChatOrder>() |
| | 12 | 520 | | .Property(x => x.CreatedAt) |
| | 12 | 521 | | .HasDefaultValueSql("CURRENT_TIMESTAMP"); |
| | 12 | 522 | | modelBuilder.Entity<OzonChatOrder>() |
| | 12 | 523 | | .Property(x => x.UpdatedAt) |
| | 12 | 524 | | .HasDefaultValueSql("CURRENT_TIMESTAMP"); |
| | | 525 | | |
| | | 526 | | // OrderReturn: возвраты Ozon, связь с Order |
| | 12 | 527 | | modelBuilder.Entity<OrderReturn>() |
| | 12 | 528 | | .HasIndex(x => x.OzonReturnId) |
| | 12 | 529 | | .IsUnique(); |
| | 12 | 530 | | modelBuilder.Entity<OrderReturn>() |
| | 12 | 531 | | .HasIndex(x => x.OrderId); |
| | 12 | 532 | | modelBuilder.Entity<OrderReturn>() |
| | 12 | 533 | | .HasIndex(x => x.PostingNumber); |
| | 12 | 534 | | modelBuilder.Entity<OrderReturn>() |
| | 12 | 535 | | .HasIndex(x => x.OzonClientId); |
| | 12 | 536 | | modelBuilder.Entity<OrderReturn>() |
| | 12 | 537 | | .HasIndex(x => x.VisualStatusSysName); |
| | | 538 | | // Составные — под fallback-поиск в UpsertBatchFromOzonReturnsAsync, когда возврат |
| | | 539 | | // не нашёлся по OzonReturnId. Одиночного индекса по PostingNumber там мало. |
| | 12 | 540 | | modelBuilder.Entity<OrderReturn>() |
| | 12 | 541 | | .HasIndex(x => new { x.OzonClientId, x.PostingNumber }); |
| | 12 | 542 | | modelBuilder.Entity<OrderReturn>() |
| | 12 | 543 | | .HasIndex(x => new { x.OzonClientId, x.OrderNumber }); |
| | | 544 | | // Фильтр по периоду на /Studio2/OrderReturns и в фильтрах заказов. |
| | 12 | 545 | | modelBuilder.Entity<OrderReturn>() |
| | 12 | 546 | | .HasIndex(x => x.VisualStatusChangeMoment); |
| | | 547 | | // OrderByDescending(UpdatedAt) — разрешение дублей в upsert и OrderReturnInfoService. |
| | 12 | 548 | | modelBuilder.Entity<OrderReturn>() |
| | 12 | 549 | | .HasIndex(x => x.UpdatedAt); |
| | 12 | 550 | | modelBuilder.Entity<OrderReturn>() |
| | 12 | 551 | | .Property(x => x.CreatedAt) |
| | 12 | 552 | | .HasDefaultValueSql("CURRENT_TIMESTAMP"); |
| | 12 | 553 | | modelBuilder.Entity<OrderReturn>() |
| | 12 | 554 | | .Property(x => x.UpdatedAt) |
| | 12 | 555 | | .HasDefaultValueSql("CURRENT_TIMESTAMP"); |
| | | 556 | | |
| | 12 | 557 | | modelBuilder.Entity<OrderReturnSyncRun>() |
| | 12 | 558 | | .HasIndex(x => x.StartedAtUtc); |
| | 12 | 559 | | modelBuilder.Entity<OrderReturnSyncRun>() |
| | 12 | 560 | | .HasIndex(x => x.Status); |
| | | 561 | | |
| | 12 | 562 | | modelBuilder.Entity<WarehouseStockSyncRun>() |
| | 12 | 563 | | .HasIndex(x => x.StartedAtUtc); |
| | 12 | 564 | | modelBuilder.Entity<WarehouseStockSyncRun>() |
| | 12 | 565 | | .HasIndex(x => x.Status); |
| | | 566 | | |
| | 12 | 567 | | modelBuilder.Entity<WarehouseStockSnapshot>() |
| | 12 | 568 | | .HasIndex(x => x.RowKey) |
| | 12 | 569 | | .IsUnique(); |
| | 12 | 570 | | modelBuilder.Entity<WarehouseStockSnapshot>() |
| | 12 | 571 | | .HasIndex(x => x.Article); |
| | 12 | 572 | | modelBuilder.Entity<WarehouseStockSnapshot>() |
| | 12 | 573 | | .HasIndex(x => x.Warehouse); |
| | 12 | 574 | | modelBuilder.Entity<WarehouseStockSnapshot>() |
| | 12 | 575 | | .HasIndex(x => x.SyncedAtUtc); |
| | 12 | 576 | | modelBuilder.Entity<WarehouseStockSnapshot>() |
| | 12 | 577 | | .HasIndex(x => x.Manufacturer); |
| | 12 | 578 | | modelBuilder.Entity<WarehouseStockSnapshot>() |
| | 12 | 579 | | .HasOne(x => x.SyncRun) |
| | 12 | 580 | | .WithMany(x => x.SnapshotRows) |
| | 12 | 581 | | .HasForeignKey(x => x.SyncRunId) |
| | 12 | 582 | | .OnDelete(DeleteBehavior.Restrict); |
| | | 583 | | |
| | 12 | 584 | | modelBuilder.Entity<InterpartsWarehouseLogin>() |
| | 12 | 585 | | .HasIndex(x => x.WarehouseId) |
| | 12 | 586 | | .IsUnique(); |
| | 12 | 587 | | modelBuilder.Entity<InterpartsWarehouseLogin>() |
| | 12 | 588 | | .HasOne(x => x.Warehouse) |
| | 12 | 589 | | .WithMany() |
| | 12 | 590 | | .HasForeignKey(x => x.WarehouseId) |
| | 12 | 591 | | .OnDelete(DeleteBehavior.Cascade); |
| | | 592 | | |
| | | 593 | | // OrderShipmentTotals: допускаем историю (много записей на один OrderId) |
| | 12 | 594 | | modelBuilder.Entity<OrderShipmentTotals>() |
| | 12 | 595 | | .HasIndex(x => x.OrderId) |
| | 12 | 596 | | .IsUnique(false); |
| | | 597 | | |
| | 12 | 598 | | modelBuilder.Entity<OrderCalculationSnapshot>() |
| | 12 | 599 | | .HasIndex(x => new { x.OrderId, x.OperationId }) |
| | 12 | 600 | | .IsUnique(); |
| | 12 | 601 | | modelBuilder.Entity<OrderCalculationSnapshot>() |
| | 12 | 602 | | .HasIndex(x => x.OperationId); |
| | | 603 | | |
| | 12 | 604 | | modelBuilder.Entity<OrderHistoryOneCPosting>() |
| | 12 | 605 | | .HasMany(p => p.HistoryLinks) |
| | 12 | 606 | | .WithOne(l => l.Posting) |
| | 12 | 607 | | .HasForeignKey(l => l.PostingId) |
| | 12 | 608 | | .OnDelete(DeleteBehavior.Cascade); |
| | | 609 | | |
| | 12 | 610 | | modelBuilder.Entity<OrderHistoryOneCPostingLink>() |
| | 12 | 611 | | .HasOne(l => l.OrderHistory) |
| | 12 | 612 | | .WithMany() |
| | 12 | 613 | | .HasForeignKey(l => l.OrderHistoryId) |
| | 12 | 614 | | .OnDelete(DeleteBehavior.Cascade); |
| | | 615 | | |
| | 12 | 616 | | modelBuilder.Entity<OrderHistoryOneCPostingLink>() |
| | 12 | 617 | | .HasIndex(l => new { l.PostingId, l.OrderHistoryId }) |
| | 12 | 618 | | .IsUnique(); |
| | | 619 | | |
| | | 620 | | // Ключ поиска карточки 1С: пара «нормализованный артикул + производитель» уникальна. |
| | 12 | 621 | | modelBuilder.Entity<OneCNomenclatureMap>() |
| | 12 | 622 | | .HasIndex(m => new { m.ArticleNorm, m.ProducerNorm }) |
| | 12 | 623 | | .IsUnique(); |
| | 12 | 624 | | modelBuilder.Entity<OneCNomenclatureMap>() |
| | 12 | 625 | | .HasIndex(m => m.OneCRefKey); |
| | 12 | 626 | | modelBuilder.Entity<OneCNomenclatureMap>() |
| | 12 | 627 | | .HasIndex(m => m.ArticleNorm); |
| | | 628 | | |
| | 12 | 629 | | modelBuilder.Entity<OneCProducerAlias>() |
| | 12 | 630 | | .HasIndex(a => a.AliasNorm) |
| | 12 | 631 | | .IsUnique(); |
| | | 632 | | |
| | | 633 | | // FidStatSnapshot → FidStatItems |
| | 12 | 634 | | modelBuilder.Entity<FidStatSnapshot>() |
| | 12 | 635 | | .HasMany(s => s.Items) |
| | 12 | 636 | | .WithOne(i => i.Snapshot) |
| | 12 | 637 | | .HasForeignKey(i => i.SnapshotId) |
| | 12 | 638 | | .OnDelete(DeleteBehavior.Cascade); |
| | 12 | 639 | | modelBuilder.Entity<FidStatSnapshot>() |
| | 12 | 640 | | .HasIndex(s => s.FidName); |
| | 12 | 641 | | modelBuilder.Entity<FidStatSnapshot>() |
| | 12 | 642 | | .HasIndex(s => s.PostTime); |
| | 12 | 643 | | modelBuilder.Entity<FidStatItem>() |
| | 12 | 644 | | .HasIndex(i => i.SnapshotId); |
| | | 645 | | |
| | | 646 | | // DataScopeSet ↔ AccessProfile: many-to-many через явную join-таблицу |
| | 12 | 647 | | modelBuilder.Entity<AccessProfile>() |
| | 12 | 648 | | .HasMany(ap => ap.DataScopeSets) |
| | 12 | 649 | | .WithMany(s => s.AccessProfiles) |
| | 24 | 650 | | .UsingEntity(j => j.ToTable("AccessProfileDataScopeSets")); |
| | | 651 | | |
| | | 652 | | // DataScopeSetItem: FK к DataScopeSet с каскадным удалением |
| | 12 | 653 | | modelBuilder.Entity<DataScopeSetItem>() |
| | 12 | 654 | | .HasOne(i => i.DataScopeSet) |
| | 12 | 655 | | .WithMany(s => s.Items) |
| | 12 | 656 | | .HasForeignKey(i => i.DataScopeSetId) |
| | 12 | 657 | | .OnDelete(DeleteBehavior.Cascade); |
| | | 658 | | |
| | | 659 | | // Email routing |
| | 12 | 660 | | modelBuilder.Entity<EmailRoutingRule>() |
| | 12 | 661 | | .HasIndex(x => new { x.IsActive, x.Priority }); |
| | | 662 | | |
| | 12 | 663 | | modelBuilder.Entity<EmailMessageInbox>() |
| | 12 | 664 | | .HasIndex(x => x.MessageExternalId) |
| | 12 | 665 | | .IsUnique(); |
| | 12 | 666 | | modelBuilder.Entity<EmailMessageInbox>() |
| | 12 | 667 | | .HasIndex(x => x.CreatedAt); |
| | 12 | 668 | | modelBuilder.Entity<EmailMessageInbox>() |
| | 12 | 669 | | .HasIndex(x => x.ProcessingStatus); |
| | | 670 | | |
| | 12 | 671 | | modelBuilder.Entity<EmailAttachmentInbox>() |
| | 12 | 672 | | .HasIndex(x => x.EmailMessageInboxId); |
| | 12 | 673 | | modelBuilder.Entity<EmailAttachmentInbox>() |
| | 12 | 674 | | .HasIndex(x => new { x.Sha256Hash, x.FileSizeBytes, x.FileName }); |
| | 12 | 675 | | modelBuilder.Entity<EmailAttachmentInbox>() |
| | 12 | 676 | | .HasOne(x => x.EmailMessage) |
| | 12 | 677 | | .WithMany(x => x.Attachments) |
| | 12 | 678 | | .HasForeignKey(x => x.EmailMessageInboxId) |
| | 12 | 679 | | .OnDelete(DeleteBehavior.Cascade); |
| | | 680 | | |
| | 12 | 681 | | modelBuilder.Entity<EmailAttachmentProcessingResult>() |
| | 12 | 682 | | .HasIndex(x => x.EmailMessageInboxId); |
| | 12 | 683 | | modelBuilder.Entity<EmailAttachmentProcessingResult>() |
| | 12 | 684 | | .HasIndex(x => x.EmailAttachmentInboxId); |
| | 12 | 685 | | modelBuilder.Entity<EmailAttachmentProcessingResult>() |
| | 12 | 686 | | .HasIndex(x => x.EmailRoutingRuleId); |
| | 12 | 687 | | modelBuilder.Entity<EmailAttachmentProcessingResult>() |
| | 12 | 688 | | .HasIndex(x => x.Status); |
| | 12 | 689 | | modelBuilder.Entity<EmailAttachmentProcessingResult>() |
| | 12 | 690 | | .HasOne(x => x.EmailMessage) |
| | 12 | 691 | | .WithMany() |
| | 12 | 692 | | .HasForeignKey(x => x.EmailMessageInboxId) |
| | 12 | 693 | | .OnDelete(DeleteBehavior.Cascade); |
| | 12 | 694 | | modelBuilder.Entity<EmailAttachmentProcessingResult>() |
| | 12 | 695 | | .HasOne(x => x.Attachment) |
| | 12 | 696 | | .WithMany(x => x.ProcessingResults) |
| | 12 | 697 | | .HasForeignKey(x => x.EmailAttachmentInboxId) |
| | 12 | 698 | | .OnDelete(DeleteBehavior.Cascade); |
| | 12 | 699 | | modelBuilder.Entity<EmailAttachmentProcessingResult>() |
| | 12 | 700 | | .HasOne(x => x.Rule) |
| | 12 | 701 | | .WithMany() |
| | 12 | 702 | | .HasForeignKey(x => x.EmailRoutingRuleId) |
| | 12 | 703 | | .OnDelete(DeleteBehavior.SetNull); |
| | | 704 | | |
| | 12 | 705 | | modelBuilder.Entity<EmailRoutingJobExecution>() |
| | 12 | 706 | | .HasIndex(x => x.StartedAtUtc); |
| | 12 | 707 | | modelBuilder.Entity<EmailRoutingJobExecution>() |
| | 12 | 708 | | .HasIndex(x => x.Status); |
| | | 709 | | |
| | 12 | 710 | | modelBuilder.Entity<OrderControlRule>(e => |
| | 12 | 711 | | { |
| | 12 | 712 | | e.HasIndex(x => x.Code).IsUnique(); |
| | 12 | 713 | | e.HasIndex(x => new { x.IsActive, x.RuleType }); |
| | 12 | 714 | | e.HasOne(x => x.TargetAppRole).WithMany().HasForeignKey(x => x.TargetAppRoleId) |
| | 12 | 715 | | .OnDelete(DeleteBehavior.Restrict); |
| | 24 | 716 | | }); |
| | 12 | 717 | | modelBuilder.Entity<OrderControlTask>(e => |
| | 12 | 718 | | { |
| | 12 | 719 | | e.HasIndex(x => x.DeduplicationKey).IsUnique(); |
| | 12 | 720 | | e.HasIndex(x => new { x.Status, x.DueAtUtc }); |
| | 12 | 721 | | e.HasIndex(x => new { x.TargetAppRoleId, x.Status }); |
| | 12 | 722 | | e.HasOne(x => x.Rule).WithMany().HasForeignKey(x => x.RuleId).OnDelete(DeleteBehavior.Restrict); |
| | 12 | 723 | | e.HasOne(x => x.Order).WithMany().HasForeignKey(x => x.OrderId).OnDelete(DeleteBehavior.Cascade); |
| | 12 | 724 | | e.HasOne(x => x.TargetAppRole).WithMany().HasForeignKey(x => x.TargetAppRoleId) |
| | 12 | 725 | | .OnDelete(DeleteBehavior.Restrict); |
| | 24 | 726 | | }); |
| | 12 | 727 | | modelBuilder.Entity<OrderControlTaskEvent>(e => |
| | 12 | 728 | | { |
| | 12 | 729 | | e.HasIndex(x => new { x.TaskId, x.CreatedAtUtc }); |
| | 12 | 730 | | e.HasOne(x => x.Task).WithMany().HasForeignKey(x => x.TaskId).OnDelete(DeleteBehavior.Cascade); |
| | 24 | 731 | | }); |
| | 12 | 732 | | modelBuilder.Entity<OrderControlExecution>().HasIndex(x => x.StartedAtUtc); |
| | | 733 | | |
| | | 734 | | // Transaction time tracking |
| | 12 | 735 | | modelBuilder.Entity<TransactionTimeTrackingSession>() |
| | 12 | 736 | | .HasIndex(x => x.TrackingKey) |
| | 12 | 737 | | .IsUnique(); |
| | 12 | 738 | | modelBuilder.Entity<TransactionTimeTrackingSession>() |
| | 12 | 739 | | .HasIndex(x => new { x.UserName, x.StartedAtUtc }); |
| | 12 | 740 | | modelBuilder.Entity<TransactionTimeTrackingSession>() |
| | 12 | 741 | | .HasIndex(x => new { x.TransactionType, x.StartedAtUtc }); |
| | 12 | 742 | | modelBuilder.Entity<TransactionTimeTrackingSession>() |
| | 12 | 743 | | .HasIndex(x => new { x.IsCompleted, x.IsAbandoned, x.StartedAtUtc }); |
| | | 744 | | |
| | 12 | 745 | | modelBuilder.Entity<TransactionTimeTrackingResult>() |
| | 12 | 746 | | .HasIndex(x => x.TrackingKey) |
| | 12 | 747 | | .IsUnique(); |
| | 12 | 748 | | modelBuilder.Entity<TransactionTimeTrackingResult>() |
| | 12 | 749 | | .HasIndex(x => new { x.UserName, x.CompletedAtUtc }); |
| | 12 | 750 | | modelBuilder.Entity<TransactionTimeTrackingResult>() |
| | 12 | 751 | | .HasIndex(x => new { x.TransactionType, x.CompletedAtUtc }); |
| | 12 | 752 | | modelBuilder.Entity<TransactionTimeTrackingResult>() |
| | 12 | 753 | | .HasIndex(x => x.TransactionId); |
| | 12 | 754 | | modelBuilder.Entity<TransactionTimeTrackingResult>() |
| | 12 | 755 | | .HasOne(x => x.TrackingSession) |
| | 12 | 756 | | .WithMany() |
| | 12 | 757 | | .HasForeignKey(x => x.TrackingSessionId) |
| | 12 | 758 | | .OnDelete(DeleteBehavior.SetNull); |
| | | 759 | | |
| | 12 | 760 | | ConfigureAuthorizationModel(modelBuilder); |
| | | 761 | | |
| | | 762 | | // ВАЖНО: фильтрация по DataScope-ам намеренно НЕ применяется как глобальный HasQueryFilter. |
| | | 763 | | // По продуктовому требованию каждый контроллер обязан явно применять scope через |
| | | 764 | | // Services.Authorization.Services.IDataScopeService — тогда логика RLS видна в коде контроллеров |
| | | 765 | | // и не «прячется» за моделью EF. |
| | | 766 | | |
| | | 767 | | // Выравнивание описывает схему MariaDB и оперирует её же особенностями — |
| | | 768 | | // в частности, одноимёнными индексами на разных таблицах (idx_execution, |
| | | 769 | | // idx_status). SQLite, на котором работают тесты, требует уникальных имён |
| | | 770 | | // индексов в пределах базы, поэтому применяем только к MySQL/MariaDB. |
| | 12 | 771 | | if (IsMySqlProvider(Database.ProviderName)) |
| | | 772 | | { |
| | 3 | 773 | | ProdSchemaAlignment.Apply(modelBuilder); |
| | | 774 | | } |
| | 12 | 775 | | } |
| | | 776 | | |
| | | 777 | | /// <summary> |
| | | 778 | | /// Конфигурация сущностей новой системы авторизации (RBAC + RLS). |
| | | 779 | | /// </summary> |
| | | 780 | | private static void ConfigureAuthorizationModel(ModelBuilder modelBuilder) |
| | | 781 | | { |
| | 12 | 782 | | modelBuilder.Entity<AppPage>(e => |
| | 12 | 783 | | { |
| | 12 | 784 | | e.ToTable("AppPages"); |
| | 12 | 785 | | e.HasIndex(p => p.Code).IsUnique(); |
| | 12 | 786 | | e.HasIndex(p => new { p.Area, p.Controller, p.Action }); |
| | 12 | 787 | | e.HasOne(p => p.Parent) |
| | 12 | 788 | | .WithMany(p => p.Children) |
| | 12 | 789 | | .HasForeignKey(p => p.ParentId) |
| | 12 | 790 | | .OnDelete(DeleteBehavior.Restrict); |
| | 24 | 791 | | }); |
| | | 792 | | |
| | 12 | 793 | | modelBuilder.Entity<AppField>(e => |
| | 12 | 794 | | { |
| | 12 | 795 | | e.ToTable("AppFields"); |
| | 12 | 796 | | e.HasIndex(f => new { f.EntityName, f.FieldName, f.FieldType }).IsUnique(); |
| | 12 | 797 | | e.HasOne(f => f.Page) |
| | 12 | 798 | | .WithMany(p => p.Fields) |
| | 12 | 799 | | .HasForeignKey(f => f.PageId) |
| | 12 | 800 | | .OnDelete(DeleteBehavior.SetNull); |
| | 24 | 801 | | }); |
| | | 802 | | |
| | 12 | 803 | | modelBuilder.Entity<DataScope>(e => |
| | 12 | 804 | | { |
| | 12 | 805 | | e.ToTable("DataScopes"); |
| | 12 | 806 | | e.HasIndex(s => s.Code).IsUnique(); |
| | 12 | 807 | | e.HasIndex(s => s.EntityName); |
| | 12 | 808 | | e.Property(s => s.FilterExpression).HasColumnType("text"); |
| | 24 | 809 | | }); |
| | | 810 | | |
| | 12 | 811 | | modelBuilder.Entity<AppRole>(e => |
| | 12 | 812 | | { |
| | 12 | 813 | | e.ToTable("AppRoles"); |
| | 12 | 814 | | e.HasIndex(r => r.Name).IsUnique(); |
| | 24 | 815 | | }); |
| | | 816 | | |
| | 12 | 817 | | modelBuilder.Entity<RolePagePermission>(e => |
| | 12 | 818 | | { |
| | 12 | 819 | | e.ToTable("RolePagePermissions"); |
| | 12 | 820 | | e.HasIndex(p => new { p.AppRoleId, p.AppPageId }).IsUnique(); |
| | 12 | 821 | | e.HasOne(p => p.AppRole) |
| | 12 | 822 | | .WithMany(r => r.PagePermissions) |
| | 12 | 823 | | .HasForeignKey(p => p.AppRoleId) |
| | 12 | 824 | | .OnDelete(DeleteBehavior.Cascade); |
| | 12 | 825 | | e.HasOne(p => p.AppPage) |
| | 12 | 826 | | .WithMany(pg => pg.RolePermissions) |
| | 12 | 827 | | .HasForeignKey(p => p.AppPageId) |
| | 12 | 828 | | .OnDelete(DeleteBehavior.Cascade); |
| | 24 | 829 | | }); |
| | | 830 | | |
| | 12 | 831 | | modelBuilder.Entity<RoleFieldPermission>(e => |
| | 12 | 832 | | { |
| | 12 | 833 | | e.ToTable("RoleFieldPermissions"); |
| | 12 | 834 | | e.HasIndex(p => new { p.AppRoleId, p.AppFieldId }).IsUnique(); |
| | 12 | 835 | | e.HasOne(p => p.AppRole) |
| | 12 | 836 | | .WithMany(r => r.FieldPermissions) |
| | 12 | 837 | | .HasForeignKey(p => p.AppRoleId) |
| | 12 | 838 | | .OnDelete(DeleteBehavior.Cascade); |
| | 12 | 839 | | e.HasOne(p => p.AppField) |
| | 12 | 840 | | .WithMany(f => f.RolePermissions) |
| | 12 | 841 | | .HasForeignKey(p => p.AppFieldId) |
| | 12 | 842 | | .OnDelete(DeleteBehavior.Cascade); |
| | 24 | 843 | | }); |
| | | 844 | | |
| | 12 | 845 | | modelBuilder.Entity<RoleDataScope>(e => |
| | 12 | 846 | | { |
| | 12 | 847 | | e.ToTable("RoleDataScopes"); |
| | 12 | 848 | | e.HasIndex(p => new { p.AppRoleId, p.DataScopeId }).IsUnique(); |
| | 12 | 849 | | e.HasOne(p => p.AppRole) |
| | 12 | 850 | | .WithMany(r => r.DataScopes) |
| | 12 | 851 | | .HasForeignKey(p => p.AppRoleId) |
| | 12 | 852 | | .OnDelete(DeleteBehavior.Cascade); |
| | 12 | 853 | | e.HasOne(p => p.DataScope) |
| | 12 | 854 | | .WithMany(s => s.RoleLinks) |
| | 12 | 855 | | .HasForeignKey(p => p.DataScopeId) |
| | 12 | 856 | | .OnDelete(DeleteBehavior.Cascade); |
| | 24 | 857 | | }); |
| | | 858 | | |
| | 12 | 859 | | modelBuilder.Entity<UserAppRole>(e => |
| | 12 | 860 | | { |
| | 12 | 861 | | e.ToTable("UserAppRoles"); |
| | 12 | 862 | | e.HasIndex(u => new { u.UserId, u.AppRoleId }).IsUnique(); |
| | 12 | 863 | | e.HasOne(u => u.AppRole) |
| | 12 | 864 | | .WithMany(r => r.UserLinks) |
| | 12 | 865 | | .HasForeignKey(u => u.AppRoleId) |
| | 12 | 866 | | .OnDelete(DeleteBehavior.Cascade); |
| | 24 | 867 | | }); |
| | | 868 | | |
| | 12 | 869 | | modelBuilder.Entity<UserPageOverride>(e => |
| | 12 | 870 | | { |
| | 12 | 871 | | e.ToTable("UserPageOverrides"); |
| | 12 | 872 | | e.HasIndex(o => new { o.UserId, o.AppPageId }).IsUnique(); |
| | 12 | 873 | | e.HasOne(o => o.AppPage) |
| | 12 | 874 | | .WithMany(p => p.UserOverrides) |
| | 12 | 875 | | .HasForeignKey(o => o.AppPageId) |
| | 12 | 876 | | .OnDelete(DeleteBehavior.Cascade); |
| | 24 | 877 | | }); |
| | | 878 | | |
| | 12 | 879 | | modelBuilder.Entity<UserFieldOverride>(e => |
| | 12 | 880 | | { |
| | 12 | 881 | | e.ToTable("UserFieldOverrides"); |
| | 12 | 882 | | e.HasIndex(o => new { o.UserId, o.AppFieldId }).IsUnique(); |
| | 12 | 883 | | e.HasOne(o => o.AppField) |
| | 12 | 884 | | .WithMany(f => f.UserOverrides) |
| | 12 | 885 | | .HasForeignKey(o => o.AppFieldId) |
| | 12 | 886 | | .OnDelete(DeleteBehavior.Cascade); |
| | 24 | 887 | | }); |
| | | 888 | | |
| | 12 | 889 | | modelBuilder.Entity<UserDataScope>(e => |
| | 12 | 890 | | { |
| | 12 | 891 | | e.ToTable("UserDataScopes"); |
| | 12 | 892 | | e.HasIndex(o => new { o.UserId, o.DataScopeId }).IsUnique(); |
| | 12 | 893 | | e.HasOne(o => o.DataScope) |
| | 12 | 894 | | .WithMany(d => d.UserLinks) |
| | 12 | 895 | | .HasForeignKey(o => o.DataScopeId) |
| | 12 | 896 | | .OnDelete(DeleteBehavior.Cascade); |
| | 24 | 897 | | }); |
| | | 898 | | |
| | 12 | 899 | | modelBuilder.Entity<AuditLogEntry>(e => |
| | 12 | 900 | | { |
| | 12 | 901 | | e.ToTable("AuthAuditLog"); |
| | 12 | 902 | | e.HasIndex(a => a.Timestamp); |
| | 12 | 903 | | e.HasIndex(a => a.ActorUserId); |
| | 12 | 904 | | e.HasIndex(a => new { a.EntityType, a.EntityId }); |
| | 12 | 905 | | e.Property(a => a.OldValue).HasColumnType("text"); |
| | 12 | 906 | | e.Property(a => a.NewValue).HasColumnType("text"); |
| | 24 | 907 | | }); |
| | | 908 | | |
| | 12 | 909 | | modelBuilder.Entity<ArmtekCartItem>(e => |
| | 12 | 910 | | { |
| | 12 | 911 | | e.HasIndex(x => new { x.ProviderKey, x.ActiveStudioOrderId }).IsUnique(); |
| | 12 | 912 | | e.HasIndex(x => new { x.ProviderKey, x.StudioOrderId, x.Status }); |
| | 12 | 913 | | e.HasIndex(x => new { x.ProviderKey, x.CreatedAtUtc }); |
| | 12 | 914 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 915 | | e.Property(x => x.SourcePrice).HasPrecision(18, 4); |
| | 12 | 916 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 24 | 917 | | }); |
| | 12 | 918 | | modelBuilder.Entity<ArmtekOrder>(e => |
| | 12 | 919 | | { |
| | 12 | 920 | | e.HasIndex(x => new { x.ProviderKey, x.Vbeln }).IsUnique(); |
| | 24 | 921 | | }); |
| | 12 | 922 | | modelBuilder.Entity<ArmtekOrderItem>(e => |
| | 12 | 923 | | { |
| | 12 | 924 | | e.HasIndex(x => x.ArmtekOrderId); |
| | 12 | 925 | | e.HasOne(x => x.ArmtekOrder).WithMany(x => x.Items).HasForeignKey(x => x.ArmtekOrderId).OnDelete(DeleteB |
| | 12 | 926 | | e.HasOne(x => x.ArmtekCartItem).WithMany().HasForeignKey(x => x.ArmtekCartItemId).OnDelete(DeleteBehavio |
| | 12 | 927 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 928 | | e.Property(x => x.Price).HasPrecision(18, 4); |
| | 12 | 929 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 24 | 930 | | }); |
| | 12 | 931 | | modelBuilder.Entity<ForumAutoCartItem>(e => |
| | 12 | 932 | | { |
| | 12 | 933 | | e.HasIndex(x => new { x.ProviderKey, x.ActiveStudioOrderId }).IsUnique(); |
| | 12 | 934 | | e.HasIndex(x => new { x.ProviderKey, x.StudioOrderId, x.Status }); |
| | 12 | 935 | | e.HasIndex(x => new { x.ProviderKey, x.CreatedAtUtc }); |
| | 12 | 936 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 937 | | e.Property(x => x.SourcePrice).HasPrecision(18, 4); |
| | 12 | 938 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 24 | 939 | | }); |
| | 12 | 940 | | modelBuilder.Entity<ForumAutoOrder>(e => |
| | 12 | 941 | | { |
| | 12 | 942 | | e.HasIndex(x => new { x.ProviderKey, x.Did }).IsUnique(); |
| | 12 | 943 | | e.HasIndex(x => new { x.ProviderKey, x.Eoid }); |
| | 24 | 944 | | }); |
| | 12 | 945 | | modelBuilder.Entity<ForumAutoOrderItem>(e => |
| | 12 | 946 | | { |
| | 12 | 947 | | e.HasIndex(x => x.ForumAutoOrderId); |
| | 12 | 948 | | e.HasOne(x => x.ForumAutoOrder).WithMany(x => x.Items).HasForeignKey(x => x.ForumAutoOrderId).OnDelete(D |
| | 12 | 949 | | e.HasOne(x => x.ForumAutoCartItem).WithMany().HasForeignKey(x => x.ForumAutoCartItemId).OnDelete(DeleteB |
| | 12 | 950 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 951 | | e.Property(x => x.Price).HasPrecision(18, 4); |
| | 12 | 952 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 24 | 953 | | }); |
| | 12 | 954 | | modelBuilder.Entity<FavoritPartsCartItem>(e => |
| | 12 | 955 | | { |
| | 12 | 956 | | e.HasIndex(x => new { x.ProviderKey, x.ActiveStudioOrderId }).IsUnique(); |
| | 12 | 957 | | e.HasIndex(x => new { x.ProviderKey, x.StudioOrderId, x.Status }); |
| | 12 | 958 | | e.HasIndex(x => new { x.ProviderKey, x.CreatedAtUtc }); |
| | 12 | 959 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 960 | | e.Property(x => x.SourcePrice).HasPrecision(18, 4); |
| | 12 | 961 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 24 | 962 | | }); |
| | 12 | 963 | | modelBuilder.Entity<FavoritPartsOrder>(e => |
| | 12 | 964 | | { |
| | 12 | 965 | | e.HasIndex(x => new { x.ProviderKey, x.ExternalOrderId }).IsUnique(); |
| | 24 | 966 | | }); |
| | 12 | 967 | | modelBuilder.Entity<FavoritPartsOrderItem>(e => |
| | 12 | 968 | | { |
| | 12 | 969 | | e.HasIndex(x => x.FavoritPartsOrderId); |
| | 12 | 970 | | e.HasOne(x => x.FavoritPartsOrder).WithMany(x => x.Items).HasForeignKey(x => x.FavoritPartsOrderId).OnDe |
| | 12 | 971 | | e.HasOne(x => x.FavoritPartsCartItem).WithMany().HasForeignKey(x => x.FavoritPartsCartItemId).OnDelete(D |
| | 12 | 972 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 973 | | e.Property(x => x.Price).HasPrecision(18, 4); |
| | 12 | 974 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 24 | 975 | | }); |
| | 12 | 976 | | modelBuilder.Entity<ProfitLigaCartItem>(e => |
| | 12 | 977 | | { |
| | 12 | 978 | | e.HasIndex(x => x.ActiveStudioOrderId).IsUnique(); |
| | 12 | 979 | | e.HasIndex(x => new { x.StudioOrderId, x.Status }); |
| | 12 | 980 | | e.HasIndex(x => x.CreatedAtUtc); |
| | 12 | 981 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 982 | | e.Property(x => x.SourcePrice).HasPrecision(18, 4); |
| | 12 | 983 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 24 | 984 | | }); |
| | 12 | 985 | | modelBuilder.Entity<ProfitLigaOrder>(e => |
| | 12 | 986 | | { |
| | 12 | 987 | | e.HasIndex(x => x.OrderNumber).IsUnique(); |
| | 24 | 988 | | }); |
| | 12 | 989 | | modelBuilder.Entity<ProfitLigaOrderItem>(e => |
| | 12 | 990 | | { |
| | 12 | 991 | | e.HasIndex(x => x.ProfitLigaOrderId); |
| | 12 | 992 | | e.HasOne(x => x.ProfitLigaOrder).WithMany(x => x.Items).HasForeignKey(x => x.ProfitLigaOrderId).OnDelete |
| | 12 | 993 | | e.HasOne(x => x.ProfitLigaCartItem).WithMany().HasForeignKey(x => x.ProfitLigaCartItemId).OnDelete(Delet |
| | 12 | 994 | | e.HasOne<Order>().WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Restrict); |
| | 12 | 995 | | e.Property(x => x.Price).HasPrecision(18, 4); |
| | 12 | 996 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 24 | 997 | | }); |
| | 12 | 998 | | modelBuilder.Entity<NikeiCartItem>(e => |
| | 12 | 999 | | { |
| | 12 | 1000 | | e.HasIndex(x => x.ActiveStudioOrderId).IsUnique(); |
| | 12 | 1001 | | e.HasIndex(x => new { x.StudioOrderId, x.Status }); |
| | 12 | 1002 | | e.HasIndex(x => x.ExternalOrderNumber); |
| | 12 | 1003 | | e.HasIndex(x => x.CreatedAtUtc); |
| | 12 | 1004 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 1005 | | e.Property(x => x.SourcePrice).HasPrecision(18, 4); |
| | 24 | 1006 | | }); |
| | 12 | 1007 | | modelBuilder.Entity<ProfitLigaPointMapping>(e => |
| | 12 | 1008 | | { |
| | 12 | 1009 | | e.HasIndex(x => x.ShipmentWarehouseId).IsUnique(); |
| | 12 | 1010 | | e.HasOne(x => x.ShipmentWarehouse).WithMany().HasForeignKey(x => x.ShipmentWarehouseId) |
| | 12 | 1011 | | .OnDelete(DeleteBehavior.Restrict); |
| | 24 | 1012 | | }); |
| | 12 | 1013 | | modelBuilder.Entity<BergCartItem>(e => |
| | 12 | 1014 | | { |
| | 12 | 1015 | | e.HasIndex(x => x.ActiveStudioOrderId).IsUnique(); |
| | 12 | 1016 | | e.HasIndex(x => new { x.StudioOrderId, x.Status }); |
| | 12 | 1017 | | e.HasIndex(x => x.CreatedAtUtc); |
| | 12 | 1018 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 1019 | | e.Property(x => x.SourcePrice).HasPrecision(18, 4); |
| | 12 | 1020 | | e.Property(x => x.MaxPrice).HasPrecision(18, 4); |
| | 12 | 1021 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 24 | 1022 | | }); |
| | 12 | 1023 | | modelBuilder.Entity<BergOrder>(e => |
| | 12 | 1024 | | { |
| | 12 | 1025 | | e.HasIndex(x => x.ExternalOrderId).IsUnique(); |
| | 12 | 1026 | | e.HasIndex(x => x.Reference).IsUnique(); |
| | 24 | 1027 | | }); |
| | 12 | 1028 | | modelBuilder.Entity<BergOrderItem>(e => |
| | 12 | 1029 | | { |
| | 12 | 1030 | | e.HasIndex(x => x.BergOrderId); |
| | 12 | 1031 | | e.HasOne(x => x.BergOrder).WithMany(x => x.Items).HasForeignKey(x => x.BergOrderId).OnDelete(DeleteBehav |
| | 12 | 1032 | | e.HasOne<BergCartItem>().WithMany().HasForeignKey(x => x.BergCartItemId).OnDelete(DeleteBehavior.SetNull |
| | 12 | 1033 | | e.HasOne<Order>().WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Restrict); |
| | 12 | 1034 | | e.Property(x => x.Price).HasPrecision(18, 4); |
| | 12 | 1035 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 24 | 1036 | | }); |
| | 12 | 1037 | | modelBuilder.Entity<BergDeliveryAddressMapping>(e => |
| | 12 | 1038 | | { |
| | 12 | 1039 | | e.HasIndex(x => x.ShipmentWarehouseId).IsUnique(); |
| | 12 | 1040 | | e.HasOne(x => x.ShipmentWarehouse).WithMany().HasForeignKey(x => x.ShipmentWarehouseId) |
| | 12 | 1041 | | .OnDelete(DeleteBehavior.Restrict); |
| | 24 | 1042 | | }); |
| | 12 | 1043 | | modelBuilder.Entity<MikadoCartItem>(e => |
| | 12 | 1044 | | { |
| | 12 | 1045 | | e.HasIndex(x => x.ActiveStudioOrderId).IsUnique(); |
| | 12 | 1046 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 1047 | | e.Property(x => x.SourcePrice).HasPrecision(18, 4); |
| | 24 | 1048 | | }); |
| | 12 | 1049 | | modelBuilder.Entity<ZZapCartItem>(e => |
| | 12 | 1050 | | { |
| | 12 | 1051 | | e.HasIndex(x => new { x.ProviderKey, x.ActiveStudioOrderId }).IsUnique(); |
| | 12 | 1052 | | e.HasIndex(x => new { x.ProviderKey, x.CodeOrder }); |
| | 12 | 1053 | | e.HasIndex(x => new { x.StudioOrderId, x.Status }); |
| | 12 | 1054 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 1055 | | e.Property(x => x.SourcePrice).HasPrecision(18, 4); |
| | 12 | 1056 | | e.Property(x => x.MinSumOrder).HasPrecision(18, 4); |
| | 24 | 1057 | | }); |
| | 12 | 1058 | | modelBuilder.Entity<MoskvorechieIstraCartItem>(e => |
| | 12 | 1059 | | { |
| | 12 | 1060 | | e.HasIndex(x => x.ActiveStudioOrderId).IsUnique(); |
| | 12 | 1061 | | e.HasIndex(x => new { x.ExternalBasketItemId, x.Status }); |
| | 12 | 1062 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 1063 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 12 | 1064 | | e.Property(x => x.SourcePrice).HasPrecision(18, 4); |
| | 24 | 1065 | | }); |
| | 12 | 1066 | | modelBuilder.Entity<MoskvorechieIstraOrder>(e => |
| | 12 | 1067 | | { |
| | 12 | 1068 | | e.HasIndex(x => x.ExternalOrderNumber).IsUnique(); |
| | 24 | 1069 | | }); |
| | 12 | 1070 | | modelBuilder.Entity<MoskvorechieIstraOrderItem>(e => |
| | 12 | 1071 | | { |
| | 12 | 1072 | | e.HasIndex(x => new { x.MoskvorechieIstraOrderId, x.StudioOrderId, x.Article }).IsUnique(); |
| | 12 | 1073 | | e.HasOne(x => x.MoskvorechieIstraOrder).WithMany(x => x.Items).HasForeignKey(x => x.MoskvorechieIstraOrd |
| | 12 | 1074 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 1075 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 12 | 1076 | | e.Property(x => x.Price).HasPrecision(18, 2); |
| | 24 | 1077 | | }); |
| | 12 | 1078 | | modelBuilder.Entity<MotexCartItem>(e => |
| | 12 | 1079 | | { |
| | 12 | 1080 | | e.HasIndex(x => x.ActiveStudioOrderId).IsUnique(); |
| | 12 | 1081 | | e.HasIndex(x => new { x.StudioOrderId, x.Status }); |
| | 12 | 1082 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 1083 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 12 | 1084 | | e.Property(x => x.SourcePrice).HasPrecision(18, 4); |
| | 24 | 1085 | | }); |
| | 24 | 1086 | | modelBuilder.Entity<MotexOrder>(e => e.HasIndex(x => x.ClientOrderNum).IsUnique()); |
| | 12 | 1087 | | modelBuilder.Entity<MotexOrderItem>(e => |
| | 12 | 1088 | | { |
| | 12 | 1089 | | e.HasIndex(x => new { x.MotexOrderId, x.StudioOrderId, x.Code }).IsUnique(); |
| | 12 | 1090 | | e.HasOne(x => x.MotexOrder).WithMany(x => x.Items).HasForeignKey(x => x.MotexOrderId).OnDelete(DeleteBeh |
| | 12 | 1091 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 12 | 1092 | | e.Property(x => x.Price).HasPrecision(18, 4); |
| | 24 | 1093 | | }); |
| | 12 | 1094 | | modelBuilder.Entity<ShateMCartItem>(e => |
| | 12 | 1095 | | { |
| | 12 | 1096 | | e.HasIndex(x => x.ActiveStudioOrderId).IsUnique(); |
| | 12 | 1097 | | e.HasIndex(x => new { x.ExternalBasketItemId, x.Status }); |
| | 12 | 1098 | | e.HasOne(x => x.StudioOrder).WithMany().HasForeignKey(x => x.StudioOrderId).OnDelete(DeleteBehavior.Rest |
| | 12 | 1099 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 12 | 1100 | | e.Property(x => x.SourcePrice).HasPrecision(18, 4); |
| | 24 | 1101 | | }); |
| | 24 | 1102 | | modelBuilder.Entity<ShateMOrder>(e => e.HasIndex(x => x.ExternalOrderId).IsUnique()); |
| | 12 | 1103 | | modelBuilder.Entity<ShateMOrderItem>(e => |
| | 12 | 1104 | | { |
| | 12 | 1105 | | e.HasIndex(x => new { x.ShateMOrderId, x.StudioOrderId, x.PriceId }).IsUnique(); |
| | 12 | 1106 | | e.HasOne(x => x.ShateMOrder).WithMany(x => x.Items).HasForeignKey(x => x.ShateMOrderId).OnDelete(DeleteB |
| | 12 | 1107 | | e.Property(x => x.Quantity).HasPrecision(18, 3); |
| | 12 | 1108 | | e.Property(x => x.Price).HasPrecision(18, 4); |
| | 24 | 1109 | | }); |
| | | 1110 | | |
| | 12 | 1111 | | modelBuilder.Entity<SupplierStatus>(e => |
| | 12 | 1112 | | { |
| | 12 | 1113 | | e.HasIndex(x => new { x.ProviderKey, x.StatusKind, x.Name }).IsUnique(); |
| | 12 | 1114 | | e.HasIndex(x => new { x.ProviderKey, x.StatusKind, x.ExternalCode }); |
| | 12 | 1115 | | e.HasOne(x => x.Supplier).WithMany().HasForeignKey(x => x.SupplierId).OnDelete(DeleteBehavior.SetNull); |
| | 12 | 1116 | | e.HasOne(x => x.StatusColor).WithMany().HasForeignKey(x => x.StatusColorId).OnDelete(DeleteBehavior.SetN |
| | 24 | 1117 | | }); |
| | | 1118 | | |
| | 12 | 1119 | | modelBuilder.Entity<OrderSupplierState>(e => |
| | 12 | 1120 | | { |
| | 12 | 1121 | | // Одна активная строка на (поставщик, заказ). Закрытые строки обнуляют ActiveOrderId |
| | 12 | 1122 | | // и выходят из-под индекса, сохраняясь для истории — приём тот же, что в ArmtekCartItems. |
| | 12 | 1123 | | e.HasIndex(x => new { x.ProviderKey, x.ActiveOrderId }).IsUnique(); |
| | 12 | 1124 | | e.HasIndex(x => x.OrderId); |
| | 12 | 1125 | | e.HasIndex(x => new { x.ProviderKey, x.Stage, x.LastSyncedAt }); |
| | 12 | 1126 | | e.HasIndex(x => x.ExternalOrderNumber); |
| | 12 | 1127 | | e.HasOne(x => x.Order).WithMany().HasForeignKey(x => x.OrderId).OnDelete(DeleteBehavior.Restrict); |
| | 12 | 1128 | | e.HasOne(x => x.SupplierStatus).WithMany().HasForeignKey(x => x.SupplierStatusId).OnDelete(DeleteBehavio |
| | 12 | 1129 | | e.Property(x => x.QuantityOrdered).HasPrecision(18, 3); |
| | 12 | 1130 | | e.Property(x => x.QuantityConfirmed).HasPrecision(18, 3); |
| | 12 | 1131 | | e.Property(x => x.QuantityShipped).HasPrecision(18, 3); |
| | 12 | 1132 | | e.Property(x => x.QuantityRejected).HasPrecision(18, 3); |
| | 24 | 1133 | | }); |
| | | 1134 | | |
| | 12 | 1135 | | modelBuilder.Entity<SupplierOrderIntent>(e => |
| | 12 | 1136 | | { |
| | 12 | 1137 | | // Одно активное намерение на (поставщик, заказ): завершённые строки обнуляют ActiveStudioOrderId |
| | 12 | 1138 | | // и выходят из-под индекса, сохраняясь для истории. Нарушение индекса = второй запрос обогнал первый. |
| | 12 | 1139 | | e.HasIndex(x => new { x.ProviderKey, x.ActiveStudioOrderId }).IsUnique(); |
| | 12 | 1140 | | e.HasIndex(x => x.StudioOrderId); |
| | 12 | 1141 | | e.HasIndex(x => new { x.Status, x.UpdatedAtUtc }); |
| | 24 | 1142 | | }); |
| | | 1143 | | |
| | 12 | 1144 | | modelBuilder.Entity<OrderSupplierStateHistory>(e => |
| | 12 | 1145 | | { |
| | 12 | 1146 | | e.HasIndex(x => new { x.OrderId, x.PerformedAt }); |
| | 12 | 1147 | | e.HasIndex(x => x.OrderHistoryId); |
| | 12 | 1148 | | e.HasOne(x => x.OrderSupplierState).WithMany().HasForeignKey(x => x.OrderSupplierStateId).OnDelete(Delet |
| | 12 | 1149 | | e.HasOne(x => x.OrderHistory).WithMany().HasForeignKey(x => x.OrderHistoryId).OnDelete(DeleteBehavior.Se |
| | 24 | 1150 | | }); |
| | | 1151 | | |
| | 12 | 1152 | | } |
| | | 1153 | | |
| | | 1154 | | /// <summary> |
| | | 1155 | | /// Провайдер MySQL/MariaDB. В тестах контекст поднимается на SQLite или |
| | | 1156 | | /// in-memory, и подгонка под боевую схему там не применяется. |
| | | 1157 | | /// </summary> |
| | | 1158 | | internal static bool IsMySqlProvider(string? providerName) => |
| | 13 | 1159 | | providerName?.Contains("MySql", StringComparison.OrdinalIgnoreCase) == true; |
| | | 1160 | | |
| | | 1161 | | } |
| | | 1162 | | } |