From c83d170000d8c75b5c91d6eadb1d08f88b2185f3 Mon Sep 17 00:00:00 2001 From: "fabien.menager" Date: Wed, 29 Oct 2025 23:22:56 +0100 Subject: [PATCH 1/2] Refactor MetadataProvider to improve table metadata retrieval logic --- .../Metadata/MetadataProvider.cs | 44 +++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/MetadataProvider.cs b/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/MetadataProvider.cs index 059b944..db5a4be 100644 --- a/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/MetadataProvider.cs +++ b/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/MetadataProvider.cs @@ -7,41 +7,39 @@ namespace PhenX.EntityFrameworkCore.BulkInsert.Metadata; internal sealed class MetadataProvider { - private Dictionary> _tablesPerContext = new(); + private readonly Dictionary> _tablesPerContext = new(); public TableMetadata GetTableInfo(DbContext context) - { - var tables = GetTables(context); - - if (!tables.TryGetValue(typeof(T), out var table)) - { - throw new InvalidOperationException($"Cannot find metadata for type '{typeof(T)}'."); - } - - return table; - } - - private Dictionary GetTables(DbContext context) { lock (_tablesPerContext) { var type = context.GetType(); - if (_tablesPerContext.TryGetValue(context.GetType(), out var tables)) + + if (!_tablesPerContext.TryGetValue(type, out var tables)) { - return tables; + tables = new Dictionary(); + _tablesPerContext[type] = tables; } - var provider = context.GetService(); + var modelType = typeof(T); + + if (tables.TryGetValue(modelType, out var table)) + { + return table; + } - tables = context.Model.GetEntityTypes() - .GroupBy(x => x.ClrType) - .ToDictionary( - x => x.Key, - x => new TableMetadata(x.First(), provider.SqlDialect)); + var entityType = context.Model.FindEntityType(modelType); + if (entityType == null) + { + throw new InvalidOperationException($"The type '{modelType.FullName}' is not part of the model for the current context."); + } + + var provider = context.GetService(); - _tablesPerContext[type] = tables; + var tableMetadata = new TableMetadata(entityType, provider.SqlDialect); + tables[modelType] = tableMetadata; - return tables; + return tableMetadata; } } } From c38316e8900786383b729f3c81894fbca3cdf6cd Mon Sep 17 00:00:00 2001 From: "fabien.menager" Date: Thu, 30 Oct 2025 18:14:16 +0100 Subject: [PATCH 2/2] Improve error handling for keyless entities in MetadataProvider --- .../Metadata/MetadataProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/MetadataProvider.cs b/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/MetadataProvider.cs index ecca12d..71c4e1f 100644 --- a/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/MetadataProvider.cs +++ b/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/MetadataProvider.cs @@ -34,11 +34,11 @@ public TableMetadata GetTableInfo(DbContext context) throw new InvalidOperationException($"The type '{modelType.FullName}' is not part of the model for the current context."); } - // Filter out entities without an associated table // See also https://learn.microsoft.com/en-us/ef/core/modeling/keyless-entity-types if (entityType.GetTableName() is null) { + throw new InvalidOperationException($"The type '{modelType.FullName}' is not mapped to a table in the database or is keyless."); } var provider = context.GetService();