diff --git a/src/PhenX.EntityFrameworkCore.BulkInsert.Oracle/OracleBulkInsertProvider.cs b/src/PhenX.EntityFrameworkCore.BulkInsert.Oracle/OracleBulkInsertProvider.cs index b97feab..36d22ff 100644 --- a/src/PhenX.EntityFrameworkCore.BulkInsert.Oracle/OracleBulkInsertProvider.cs +++ b/src/PhenX.EntityFrameworkCore.BulkInsert.Oracle/OracleBulkInsertProvider.cs @@ -59,7 +59,20 @@ protected override Task BulkInsert( using var bulkCopy = new OracleBulkCopy(connection, options.CopyOptions); - bulkCopy.DestinationTableName = tableName; + // OracleBulkCopy's direct-path load cannot handle schema-qualified table names. + // When a schema is configured (e.g. via HasDefaultSchema()), the QuotedTableName + // includes a schema prefix (e.g. "SchemaX"."TableA"), which ODP.NET double-applies, + // producing SchemaX.SchemaX.TableA (ORA-39831). Use DestinationSchemaName explicitly. + if (tableName == tableInfo.QuotedTableName && tableInfo.Schema != null) + { + bulkCopy.DestinationTableName = SqlDialect.Quote(tableInfo.TableName); + bulkCopy.DestinationSchemaName = tableInfo.Schema; + } + else + { + bulkCopy.DestinationTableName = tableName; + } + bulkCopy.BatchSize = options.BatchSize; bulkCopy.BulkCopyTimeout = options.GetCopyTimeoutInSeconds(); diff --git a/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/TableMetadata.cs b/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/TableMetadata.cs index 17028b7..28f6f56 100644 --- a/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/TableMetadata.cs +++ b/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/TableMetadata.cs @@ -12,6 +12,8 @@ internal sealed class TableMetadata private readonly IEntityType _entityType; + public string? Schema { get; } + public string QuotedTableName { get; } public string TableName { get; } @@ -21,8 +23,9 @@ internal sealed class TableMetadata public TableMetadata(IEntityType entityType, SqlDialectBuilder dialect) { _entityType = entityType; + Schema = entityType.GetSchema(); TableName = entityType.GetTableName() ?? throw new InvalidOperationException("Cannot determine table name."); - QuotedTableName = dialect.QuoteTableName(entityType.GetSchema(), TableName); + QuotedTableName = dialect.QuoteTableName(Schema, TableName); Columns = GetColumns(entityType, dialect); }