Closed
Description
Ciao!
I've reproduced the issue there:
https://github.com/lucax88x/dapper-bug
So, if you have a postgresql db, and you use a jsonb column, and you use netwonsoft as deserializer such as:
NpgsqlConnection.GlobalTypeMapper.UseJsonNet(settings: settings);
and perform a a query like
await conn.QueryFirstOrDefaultAsync<string>("select \"Content\" from public.\"Posts\"");
will throw an exception with
---> System.InvalidCastException: Object must implement IConvertible.
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at Dapper.SqlMapper.GetValue[T](DbDataReader reader, Type effectiveType, Object val) in /_/Dapper/SqlMapper.cs:line 1366
--- End of inner exception stack trace ---
at Dapper.SqlMapper.ThrowDataException(Exception ex, Int32 index, IDataReader reader, Object value) in /_/Dapper/SqlMapper.cs:line 3928
at Dapper.SqlMapper.QueryRowAsync[T](IDbConnection cnn, Row row, Type effectiveType, CommandDefinition command) in /_/Dapper/SqlMapper.Async.cs:line 496
This happens only with 2.1.*, if I revert to 2.0.151 everything works perfectly.
This is probably the PR that breaks it.
ps: without json.net it also work perfectly, it's just a combination of json.net and jsonb.
Metadata
Metadata
Assignees
Labels
No labels
Activity
mgravell commentedon Mar 5, 2024
I imagine that what's happening here is that npgsql is doing the deserialize, and giving us something that isn't a string (but rather: a rich object) - and we're expecting it to be a string. This is probably related to Dapper (vanilla) using the untyped data read API in some cases. Dapper.AOT does a better job of preferring typed data, so I imagine that Dapper.AOT would explicitly request a string, and receive a string. Any chance you can try the same query with Dapper AOT enabled? Or provide a full repro?
lucax88x commentedon Mar 5, 2024
There's a github link with a full repro on top.
Clone the repo, and run the tests, it will fire up a db with test containers and run the query.
I can try with AOT tomorrow!
mgravell commentedon Mar 6, 2024
See https://aot.dapperlib.dev/gettingstarted
mgravell commentedon Mar 6, 2024
apologies, I overlooked the repro; taking a peek
mgravell commentedon Mar 6, 2024
nit:
await using var conn = new NpgsqlConnection(_connectionString);
, but: great repro, thanks - lookingmgravell commentedon Mar 6, 2024
I'm a little confused... it... works? (I haven't changed anything except the connection string)
and at the command-line:
What should I be seeing?
mgravell commentedon Mar 6, 2024
it is possible that this can be fixed with a one-liner in SqlMapper.cs L217:
can check as soon as we can repro
on a per-consumer-project basis, we can check this with
lucax88x commentedon Mar 6, 2024
Wow.
This is extremely weird, I lost two hours for that.
So, stay with me:
update the git repo
run the compose from the root
docker compose -f docker-compose.yml up
now, you have 2 tests from the solution
-CreateTables
-RunAloneNotTogetherWithCreateTables
But, if for some reason, you try to run both of them together, CreateTables will fail because table is already there (which is OK), but the RunAloneNotTogetherWithCreateTables will be green (WTF?)!
Something must happening with assembly...
Gonna try with your map.
lucax88x commentedon Mar 6, 2024
I can confirm it works.
mgravell commentedon Mar 6, 2024
great; that's a workaround, and we'll get the code fixed for next release
mgravell commentedon Mar 6, 2024
so... I don't think it is connecting to the containerized database, but... I think we understand the problem well enough now
lucax88x commentedon Mar 6, 2024
Create the db in the container :)
lucax88x commentedon Mar 6, 2024
thanks for the quick answer btw.
17 remaining items