Not able to use the package with .NET 9
The following error comes up when you upgrade to .NET 9.
Warning As Error: Detected package version outside of dependency constraint: Pomelo.EntityFrameworkCore.MySql 8.0.2 requires Microsoft.EntityFrameworkCore.Relational (>= 8.0.2 && <= 8.0.999) but version Microsoft.EntityFrameworkCore.Relational 9.0.0 was resolved.
I think we need to either upgrade Pomelo.EntityFrameworkCore to support .NET 9 or find a replacement.
This is specifically for the MySql package which I am not using at the moment. I decided to install just the SqlServer package and that worked for me. Closing this issue.
Will check it out for MY as well, soon when new version gets added.
I didn't have success with PGSQL either. I will re-check it in the coming days.
I will reopen the issue as the actual problem is still not solved due to an external dependency.
Pomelo for MySql has preRelease 9 but even that has some companitibilty issues. Still they said that Release version would be published this or next week, so will update it to 9 as soon as they publish it. If it does not get published till the end of November will then try to publish prerelease of Bulk 9 as well.
v9.0.0-rc.1 is now published on nuget. Will be updated to full release as soon as Mysql v9 is also fully release, expecting it to be in a few days.
I have installed the preview version and tried it. Getting the same error that I mentioned in #1620
at EFCore.BulkExtensions.IQueryableExtensions.ToParametrizedSql(IQueryable query)
at EFCore.BulkExtensions.BatchUtil.GetBatchSql(IQueryable query, DbContext context, Boolean isUpdate)
at EFCore.BulkExtensions.SqlAdapters.SqlQueryBuilder.MergeTable[T](DbContext context, TableInfo tableInfo, OperationType operationType, IEnumerable1 entityPropertyWithDefaultValue) at EFCore.BulkExtensions.SqlAdapters.SqlServer.SqlServerAdapter.<MergeAsync>d__91.MoveNext()
at EFCore.BulkExtensions.SqlAdapters.SqlServer.SqlServerAdapter.<MergeAsync>d__91.MoveNext() at EFCore.BulkExtensions.SqlAdapters.SqlServer.SqlServerAdapter.<MergeAsync>d__81.MoveNext()
at EFCore.BulkExtensions.SqlBulkOperation.<MergeAsync>d__51.MoveNext() at EFCore.BulkExtensions.DbContextBulkTransaction.<ExecuteAsync>d__11.MoveNext()
@evicio1 are you using one of configs SynchronizeFilter or SynchronizeSoftDelete ?
Yes, SynchronizeFilter.
ex:
await context.BulkInsertOrUpdateOrDeleteAsync(dto, options =>
{
options.UpdateByProperties = ["Code"];
options.PropertiesToExcludeOnUpdate = [
"Percentage","Description","CountryCode",];
options.SetSynchronizeFilter<MonthlySalary>(x => x.code == "TEST");
}, cancellationToken: cancellationToken);
@evicio1 Can you write entire test for this (or alter existing one for BulkSync), not able to repreduce it. Still I can see where the bug is but don't have the sollution at the moment.
This is specifically for the MySql package which I am not using at the moment. I decided to install just the SqlServer package and that worked for me. Closing this issue.
We're not using any MySql packages but I am not able to update Microsoft.EntityFrameworkCore.SqlServer package to 9.0.0 because of the following error:
EFCore.BulkExtensions 8.1.2 -> EFCore.BulkExtensions.MySql 8.1.2 -> Pomelo.EntityFrameworkCore.MySql 8.0.2 -> Microsoft.EntityFrameworkCore.Relational (>= 8.0.2 && <= 8.0.999).
These are our relevant nuget packages: EFCore.BulkExtensions v8.1.2 Microsoft.EntityFrameworkCore v8.0.11 Microsoft.EntityFrameworkCore.SqlServer v8.0.11
@borisdj
It seems the issue lies with IQueryableExtensions.ToParametrizedSql(). In EF Core 9, it appears that retrieving RelationalCommandCache using the following approach is no longer working:
var relationalCommandCache = (RelationalCommandCache?)enumerator.Private(relationalCommandCacheText);
I implemented a small fix that seems to resolve the issue. Could you please review it?
string relationalCommandResolverText = "_relationalCommandResolver";
var relationalCommandResolver = enumerator.Private<Delegate>(relationalCommandResolverText);
command = (IRelationalCommand)relationalCommandResolver.DynamicInvoke(parameterValues);
public static class IQueryableExtensions
{
/// <summary>
/// Extension method to paramatize sql query
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public static (string, IEnumerable<DbParameter>) ToParametrizedSql(this IQueryable query)
{
string relationalQueryContextText = "_relationalQueryContext";
string relationalCommandCacheText = "_relationalCommandCache";
string relationalCommandResolverText = "_relationalCommandResolver";
string cannotGetText = "Cannot get";
#pragma warning disable CS8602 // Dereference of a possibly null reference.
var enumerator = query.Provider.Execute<IEnumerable>(query.Expression).GetEnumerator();
#pragma warning restore CS8602 // Dereference of a possibly null reference.
var queryContext = enumerator.Private<RelationalQueryContext>(relationalQueryContextText) ?? throw new InvalidOperationException($"{cannotGetText} {relationalQueryContextText}");
var parameterValues = queryContext.ParameterValues;
#pragma warning disable EF1001 // Internal EF Core API usage.
var relationalCommandCache = (RelationalCommandCache?)enumerator.Private(relationalCommandCacheText);
var relationalCommandResolver = enumerator.Private<Delegate>(relationalCommandResolverText);
#pragma warning restore EF1001
IRelationalCommand command;
if (relationalCommandResolver != null)
{
#pragma warning disable EF1001 // Internal EF Core API usage.
command = (IRelationalCommand)relationalCommandResolver.DynamicInvoke(parameterValues);
//command = (IRelationalCommand)relationalCommandCache.GetRelationalCommandTemplate(parameterValues);
#pragma warning restore EF1001
}
else
{
string selectExpressionText = "_selectExpression";
string querySqlGeneratorFactoryText = "_querySqlGeneratorFactory";
SelectExpression selectExpression = enumerator.Private<SelectExpression>(selectExpressionText) ?? throw new InvalidOperationException($"{cannotGetText} {selectExpressionText}");
IQuerySqlGeneratorFactory factory = enumerator.Private<IQuerySqlGeneratorFactory>(querySqlGeneratorFactoryText) ?? throw new InvalidOperationException($"{cannotGetText} {querySqlGeneratorFactoryText}");
command = factory.Create().GetCommand(selectExpression);
}
string sql = command.CommandText;
IList<DbParameter> parameters;
try
{
using var dbCommand = SqlAdaptersMapping.DbServer.QueryBuilder.CreateCommand(); // Use a DbCommand to convert parameter values using ValueConverters to the correct type.
foreach (var param in command.Parameters)
{
var values = parameterValues[param.InvariantName];
param.AddDbParameter(dbCommand, values);
}
parameters = new List<DbParameter>(dbCommand.Parameters.OfType<DbParameter>());
dbCommand.Parameters.Clear();
}
catch (Exception ex) // Fix for BatchDelete with 'uint' param on Sqlite. TEST: RunBatchUint
{
var npgsqlSpecParamMessage = "Npgsql-specific type mapping ";
// Full Msg:
// "Npgsql-specific type mapping Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping.NpgsqlArrayListTypeMapping being used with non-Npgsql parameter type SqlParameter"
// "Npgsql-specific type mapping NpgsqlTimestampTzTypeMapping being used with non-Npgsql parameter type SqlParameter" // for Batch (a < date)
if (ex.Message.StartsWith("No mapping exists from DbType") && ex.Message.EndsWith("to a known SqlDbType.") || // example: "No mapping exists from DbType UInt32 to a known SqlDbType."
ex.Message.StartsWith(npgsqlSpecParamMessage)) // Fix for BatchDelete with Contains on PostgreSQL
{
var parameterNames = new HashSet<string>(command.Parameters.Select(p => p.InvariantName));
parameters = parameterValues.Where(pv => parameterNames.Contains(pv.Key)).Select(pv => SqlAdaptersMapping.DbServer.QueryBuilder.CreateParameter("@" + pv.Key, pv.Value)).ToList();
}
else
{
throw;
}
}
return (sql, parameters);
}
@evicio1 I have integrate it and made a commit. Can you take the latest source and check that it works for you case.
Also provider specific nugets for MS, PG and LT are now published in full release 9.0.0. MY is not and also Main, that has all providers, is not since MySql {review version has dependency conflict with Release.
I have tested and it's all good. Thank you @borisdj
When will this fix be available for net core 9.0
Any update on this at all? Would love to move to EF9 but can't and EF8 is now giving vulnerability issues...
Tested today with 9_rc1. Still the same issue
Cannot get _selectExpression
IQueryableExtensions.ToParametrizedSql(IQueryable query)
BatchUtil.GetBatchSql(IQueryable query, DbContext context, Boolean isUpdate)
SqlQueryBuilder.MergeTable[T](DbContext context, TableInfo tableInfo, OperationType operationType, IEnumerable`1 entityPropertyWithDefaultValue)
SqlServerAdapter.MergeAsync[T](DbContext context, Type type, IEnumerable`1 entities, TableInfo tableInfo, OperationType operationType, Action`1 progress, Boolean isAsync, CancellationToken cancellationToken)
SqlServerAdapter.MergeAsync[T](DbContext context, Type type, IEnumerable`1 entities, TableInfo tableInfo, OperationType operationType, Action`1 progress, Boolean isAsync, CancellationToken cancellationToken)
SqlServerAdapter.MergeAsync[T](DbContext context, Type type, IEnumerable`1 entities, TableInfo tableInfo, OperationType operationType, Action`1 progress, CancellationToken cancellationToken)
SqlBulkOperation.MergeAsync[T](DbContext context, Type type, IEnumerable`1 entities, TableInfo tableInfo, OperationType operationType, Action`1 progress, CancellationToken cancellationToken)
DbContextBulkTransaction.ExecuteAsync[T](DbContext context, Type type, IEnumerable`1 entities, OperationType operationType, BulkConfig bulkConfig, Action`1 progress, CancellationToken cancellationToken)
I'm using the RC1 and the only issue I'm getting is build warning as I'm using EF 9.0.1 and not EF 9.0.0, however it does build and run
If I decompile the 9.0.1 version than I still missing the fix public static (string, IEnumerable<DbParameter>) ToParametrizedSql(this IQueryable query) { string relationalQueryContextText = "_relationalQueryContext"; string relationalCommandCacheText = "_relationalCommandCache"; string relationalCommandResolverText = "_relationalCommandResolver";
New versions with latest source are published v 8.1.3 for EF8 and v 9.0.1 for EF9. Make a test for the issue with these versions.
Hello, I use EFCore v 9.0.2 and installed EfCore.BulkExtensions v 9.0.1 but in the using statement the namespace could not be found :-( VS version: Microsoft Visual Studio Enterprise 2022 (64-bit) - Current Version 17.12.1