Open Richard87 opened 3 hours ago
Current solution 🧸
var conditions = entry.Select(x => $"'{x.Escaped()}'").Join(",");
qb = qb.Where(x => x.MatchesJsonPath($"data['VerifiedHealthResults']['{entry.Key.Escaped()}'] ?| array[{conditions}]"));
and
public static class PostgresqlStringEscape
{
public static string Escaped(this string s) => s.Replace("'", "''");
}
not great :/
@Richard87 What is it you expect to happen here? I think this is an "I take pull requests" kind of issue. I feel like I gave you workarounds that would have been easier than what you ended up doing.
I expect that parameters in a json Path works...
I don't think reorganizing the data in a different way would help me in this case (this is already v2 of the projection to allow all the queries we need).
I would love to look at submitting a PR to fix it, but was struggling to understand the code while debugging it, could you give some pointers on where the key elements are in the code?
"I don't think reorganizing the data in a different way would help me in this case (this is already v2 of the projection to allow all the queries we need)." -- all you had to do was make a calculated property with the array of values within the one slot on the dictionary. That would have been so much easier than what you did.
It's open source code man, first thing I would do is trace the code and the Weasel helpers. You can do the exact same thing. The LINQ support isn't approachable in the slightest and I'm not personally willing to spend the time that would take to do what your model was forcing you to do, but taking on something to make the straight up SQL approach easier isn't that bad.
Possibly related to #3045
I'm struggling to add parameters to a
MatchesJSONPath
call... I have tried this;Details
```text System.InvalidCastException: Writing values of 'Weasel.Postgresql.SqlGeneration.CommandParameter' is not supported for parameters having NpgsqlDbType 'Text'. at Npgsql.Internal.AdoSerializerHelpers.g__ThrowWritingNotSupported|1_0(Type type, PgSerializerOptions options, Nullable`1 pgTypeId, Nullable`1 npgsqlDbType, Exception inner)
at Npgsql.Internal.AdoSerializerHelpers.GetTypeInfoForWriting(Type type, Nullable`1 pgTypeId, PgSerializerOptions options, Nullable`1 npgsqlDbType)
at Npgsql.NpgsqlParameter.ResolveTypeInfo(PgSerializerOptions options)
at Npgsql.NpgsqlParameterCollection.ProcessParameters(PgSerializerOptions options, Boolean validateValues, CommandType commandType)
at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
at Marten.Internal.Sessions.AutoClosingLifetime.ExecuteReaderAsync(NpgsqlBatch batch, CancellationToken token)
at Marten.Internal.Sessions.AutoClosingLifetime.ExecuteReaderAsync(NpgsqlBatch batch, CancellationToken token)
at Marten.Linq.MartenLinqQueryProvider.ExecuteHandlerAsync[T](IQueryHandler`1 handler, CancellationToken token)
at JasperFx.Core.Exceptions.ExceptionTransformExtensions.TransformAndThrow(IEnumerable`1 transforms, Exception ex)
at JasperFx.Core.Exceptions.ExceptionTransforms.TransformAndThrow(Exception ex)
at Marten.Exceptions.MartenExceptionTransformer.WrapAndThrow(Exception exception)
at Marten.Linq.MartenLinqQueryProvider.ExecuteHandlerAsync[T](IQueryHandler`1 handler, CancellationToken token)
at Marten.Linq.MartenLinqQueryable`1.ToListAsync[TResult](CancellationToken token)
at Happydogs.ReadModels.SearchV2Endpoint.Get(IQuerySession session, CancellationToken ct, ILogger`1 logger, String query, String locations, String breeds, Boolean includeDogs, Boolean includeBreeders, Boolean includeLitters, Nullable`1 dogIsMale, Nullable`1 dogIsAvailableForBreeder, String healthResults, Nullable`1 litterFollowsNkkGuidelines, Nullable`1 litterFollowsClubGuidelines, Nullable`1 litterIsAvailable, Nullable`1 breederPlannedLitters, Nullable`1 breederLittersAvailable) in C:\Users\Richard\Projects\happydogs\backend\Happydogs\ReadModels\SearchV2Projection.cs:line 378
at Internal.Generated.WolverineHandlers.GET_api_search_v2.Handle(HttpContext httpContext) in C:\Users\Richard\Projects\happydogs\backend\Web\Internal\Generated\WolverineHandlers\GET_api_search_v2.cs:line 64
at Internal.Generated.WolverineHandlers.GET_api_search_v2.Handle(HttpContext httpContext) in C:\Users\Richard\Projects\happydogs\backend\Web\Internal\Generated\WolverineHandlers\GET_api_search_v2.cs:line 67
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
```
And this:
Details
```text System.NotSupportedException: Can't infer NpgsqlDbType for type <>f__AnonymousType1`1[j__TPar]
at Weasel.Core.DatabaseProvider`3.ToParameterType(Type type)
at Weasel.Postgresql.PostgresqlProvider.determineParameterType(Type type, NpgsqlDbType& dbType)
at Weasel.Core.DatabaseProvider`3.TryGetDbType(Type type)
at Weasel.Postgresql.SqlGeneration.CommandParameter..ctor(Object value)
at Marten.Linq.MatchesSql.MatchesJsonPathParser.<>c.b__2_0(Object x)
at System.Linq.Enumerable.SelectArrayIterator`2.Fill(ReadOnlySpan`1 source, Span`1 destination, Func`2 func)
at System.Linq.Enumerable.SelectArrayIterator`2.ToArray()
at Marten.Linq.MatchesSql.MatchesJsonPathParser.Parse(IQueryableMemberCollection memberCollection, IReadOnlyStoreOptions options, MethodCallExpression expression)
at Marten.Linq.Parsing.WhereClauseParser.VisitMethodCall(MethodCallExpression node)
at Marten.Linq.Parsing.WhereClauseParser.Visit(Expression node)
at Marten.Linq.SqlGeneration.Statement.ParseWhereClause(IReadOnlyList`1 wheres, IMartenSession session, IQueryableMemberCollection collection, IDocumentStorage storage)
at Marten.Linq.CollectionUsage.BuildTopStatement(IMartenSession session, IQueryableMemberCollection collection, IDocumentStorage storage, QueryStatistics statistics)
at Marten.Linq.Parsing.LinqQueryParser.BuildStatements()
at Marten.Linq.Parsing.LinqQueryParser.BuildListHandler[T]()
at Marten.Linq.MartenLinqQueryable`1.ToListAsync[TResult](CancellationToken token)
at Happydogs.ReadModels.SearchV2Endpoint.Get(IQuerySession session, CancellationToken ct, ILogger`1 logger, String query, String locations, String breeds, Boolean includeDogs, Boolean includeBreeders, Boolean includeLitters, Nullable`1 dogIsMale, Nullable`1 dogIsAvailableForBreeder, String healthResults, Nullable`1 litterFollowsNkkGuidelines, Nullable`1 litterFollowsClubGuidelines, Nullable`1 litterIsAvailable, Nullable`1 breederPlannedLitters, Nullable`1 breederLittersAvailable) in C:\Users\Richard\Projects\happydogs\backend\Happydogs\ReadModels\SearchV2Projection.cs:line 380
at Internal.Generated.WolverineHandlers.GET_api_search_v2.Handle(HttpContext httpContext) in C:\Users\Richard\Projects\happydogs\backend\Web\Internal\Generated\WolverineHandlers\GET_api_search_v2.cs:line 64
at Internal.Generated.WolverineHandlers.GET_api_search_v2.Handle(HttpContext httpContext) in C:\Users\Richard\Projects\happydogs\backend\Web\Internal\Generated\WolverineHandlers\GET_api_search_v2.cs:line 67
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
```
Version: