I would like to return all the rows that contains a price higher than 123:
// Entity Table1
[Column(TypeName = "jsonb")]
public List<NewPrice> HistoryPrices { get; set; }
public class NewPrice
{
public int Price { get; set; }
public DateTimeOffset Date { get; set; }
}
This fails as it can’t translate the linq query to sql query:
_dbContext.Table1
.Where(p => p.HistoryPrices[0].Price > 123)
postgresql query that works fine would be something like this:
SELECT history_prices, *
FROM Table1
WHERE jsonb_path_exists(
history_prices,
'$[0] ? (@.Price > 123)'
);
Can’t see which EF.Functions would fit the case.
1/ I don’t want to run the query locally using AsEnumerable().
2/ I don’t want to change the table structure
Any idea?
Thank you
2
Answers
As documented, mapping directly to
jsonb
POCO columns is deprecated, and does not support many types of queries.You need to set up your model properly with Owned JSON properties.
Your mapping aside, it looks like functions using PostgreSQL JSONPath aren’t supported in npgsql yet. In the meanwhile, you can use raw SQL if you really need them.
Instead of
jsonb_path_exists()
it might make more sense to use@@
to let it use an index:The
.Where
above suggests how you could also try to do that without JSONPath (won’t use an index unless it’s an expression index on exactly that):And that’s fairly simple to translate to a LinQ against a JSON column as long as you can change the way you’re mapping your entities. Npgsql shows an example of pretty much exactly that: