From 5613cf986e0aa716cd35ba8f9fe3045b052a0aa9 Mon Sep 17 00:00:00 2001 From: Micaiah Martin Date: Fri, 10 Apr 2026 10:09:04 -0600 Subject: [PATCH 1/2] Fix CollectionUser and CollectionGroup table names across all DB providers --- util/Seeder/Pipeline/BulkCommitter.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/util/Seeder/Pipeline/BulkCommitter.cs b/util/Seeder/Pipeline/BulkCommitter.cs index 53768fa5ff69..0787fc648047 100644 --- a/util/Seeder/Pipeline/BulkCommitter.cs +++ b/util/Seeder/Pipeline/BulkCommitter.cs @@ -2,6 +2,7 @@ using Bit.Infrastructure.EntityFramework.Repositories; using LinqToDB.Data; using LinqToDB.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using EfCollection = Bit.Infrastructure.EntityFramework.Models.Collection; using EfCollectionGroup = Bit.Infrastructure.EntityFramework.Models.CollectionGroup; using EfCollectionUser = Bit.Infrastructure.EntityFramework.Models.CollectionUser; @@ -24,8 +25,8 @@ namespace Bit.Seeder.Pipeline; /// Each list is cleared after insert so the context is ready for the next pipeline run. /// /// CollectionUser and CollectionGroup require an explicit table name in BulkCopyOptions because -/// they lack both IEntityTypeConfiguration and .ToTable() mappings in DatabaseContext, so LinqToDB -/// cannot resolve their table names automatically. +/// they lack IEntityTypeConfiguration mappings in DatabaseContext. Table names vary by provider — +/// SQL Server uses singular names while EF Core-managed providers use pluralized names. /// /// /// @@ -45,9 +46,11 @@ internal void Commit(SeederContext context) MapCopyAndClear(context.Collections); - MapCopyAndClear(context.CollectionUsers, nameof(Core.Entities.CollectionUser)); + MapCopyAndClear(context.CollectionUsers, + GetTableName()); - MapCopyAndClear(context.CollectionGroups, nameof(Core.Entities.CollectionGroup)); + MapCopyAndClear(context.CollectionGroups, + GetTableName()); MapCopyAndClear(context.Folders); @@ -56,6 +59,15 @@ internal void Commit(SeederContext context) CopyAndClear(context.CollectionCiphers); } + /// + /// Resolves the table name for an EF entity type from the EF Core model, + /// falling back to the C# class name for SQL Server. + /// + private string? GetTableName() where TEf : class => + db.Database.IsSqlServer() + ? typeof(TEf).Name + : db.Model.FindEntityType(typeof(TEf))?.GetTableName(); + private void MapCopyAndClear(List entities, string? tableName = null) where TEf : class { if (entities.Count is 0) From e6d003bc64eab26679a0b33b3d9a7c64d0e1e3e2 Mon Sep 17 00:00:00 2001 From: Micaiah Martin Date: Fri, 10 Apr 2026 10:14:33 -0600 Subject: [PATCH 2/2] Correct comment accuracy --- util/Seeder/Pipeline/BulkCommitter.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/util/Seeder/Pipeline/BulkCommitter.cs b/util/Seeder/Pipeline/BulkCommitter.cs index 0787fc648047..77430fa75fb2 100644 --- a/util/Seeder/Pipeline/BulkCommitter.cs +++ b/util/Seeder/Pipeline/BulkCommitter.cs @@ -25,8 +25,9 @@ namespace Bit.Seeder.Pipeline; /// Each list is cleared after insert so the context is ready for the next pipeline run. /// /// CollectionUser and CollectionGroup require an explicit table name in BulkCopyOptions because -/// they lack IEntityTypeConfiguration mappings in DatabaseContext. Table names vary by provider — -/// SQL Server uses singular names while EF Core-managed providers use pluralized names. +/// they lack .ToTable() mappings in DatabaseContext, so LinqToDB cannot resolve their table names +/// automatically. Table names vary by provider — SQL Server uses singular names while EF Core-managed +/// providers use pluralized names. /// /// ///