Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix BatchDelete and BatchUpdate with where expression and ValueConverter #497

Merged
merged 1 commit into from
Mar 22, 2021

Conversation

jr01
Copy link
Contributor

@jr01 jr01 commented Mar 22, 2021

Hello again :)

When using something like:

var date = new LocalDate(2020, 3, 21);
dbContext.Model.Where(x => x.LocalDate > date).BatchDelete()

I got this exception:

System.ArgumentException: No mapping exists from object type EFCore.BulkExtensions.Tests.ValueConverters.LocalDate to a known managed provider native type.
	at Microsoft.Data.SqlClient.MetaType.GetMetaTypeFromValue(Type dataType, Object value, Boolean inferLen, Boolean streamAllowed)
	at Microsoft.Data.SqlClient.MetaType.GetMetaTypeFromType(Type dataType)
	at Microsoft.Data.SqlClient.SqlParameter.GetMetaTypeOnly()
	at Microsoft.Data.SqlClient.SqlParameter.get_DbType()
	at EFCore.BulkExtensions.SQLAdapters.SQLServer.SqlServerDialect.ReloadSqlParameters(DbContext context, List`1 sqlParameters)
	at EFCore.BulkExtensions.BatchUtil.ReloadSqlParameters(DbContext context, List`1 sqlParameters)
	at EFCore.BulkExtensions.BatchUtil.GetSqlDelete(IQueryable query, DbContext context)
	...

The problem was that CheckAndSetParametersForConvertibles only applied the converter when if (convertibleProperty.Key.ToLower() == parameterColumnName) and that isn't the case here: convertibleProperty.Key = 'LocalDate' and parameterColumnName = 'date'. And also the CheckAndSetParametersForConvertibles only worked when dealing with a string database type.

The solution is to let EF Core convert the parameter itself using IRelationalParameter.AddDbParameter(dbCommand, values); in ToParametrizedSql().

I'm not sure if this fix also needs to be in the else part of ToParametrizedSql() when relationalCommandCache == null, because I have no clue how to trigger that branch with EF Core 3.1 ...

@borisdj borisdj merged commit 9e214aa into borisdj:master Mar 22, 2021
@borisdj
Copy link
Owner

borisdj commented Mar 22, 2021

That was how it worked, param name had to be same as of property: #397 (comment)
But it was not best solution, more as a temporary.
I've moved setting params below if-else segment so that it works for both.
Thx for the fix, v3.4.8 published.

Also I am not sure how to test relationalCommandCache being null.
It was a PR #270 from @halllo Do you know when will relationalCommandCache = null to make a test it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants