From 5778c7c41814e46637c93c3ac39beee503c6aa30 Mon Sep 17 00:00:00 2001 From: Weilence Date: Wed, 24 Jan 2024 23:20:08 +0800 Subject: [PATCH] Add translator for hstore type --- .../Internal/NpgsqlHstoreTranslator.cs | 59 +++++++++++++++++++ .../NpgsqlMethodCallTranslatorProvider.cs | 1 + 2 files changed, 60 insertions(+) create mode 100644 src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlHstoreTranslator.cs diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlHstoreTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlHstoreTranslator.cs new file mode 100644 index 000000000..7613567bb --- /dev/null +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlHstoreTranslator.cs @@ -0,0 +1,59 @@ +using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping; + +namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Internal; + +/// +/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to +/// the same compatibility standards as public APIs. It may be changed or removed without notice in +/// any release. You should only use it directly in your code with extreme caution and knowing that +/// doing so can result in application failures when updating to a new Entity Framework Core release. +/// +public class NpgsqlHstoreTranslator : IMethodCallTranslator +{ + private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; + private readonly RelationalTypeMapping? _stringTypeMapping; + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public NpgsqlHstoreTranslator( + IRelationalTypeMappingSource typeMappingSource, + NpgsqlSqlExpressionFactory sqlExpressionFactory, + IModel model) + { + _sqlExpressionFactory = sqlExpressionFactory; + _stringTypeMapping = typeMappingSource.FindMapping(typeof(string), model)!; + } + + private static readonly MethodInfo _methodInfo = typeof(Dictionary).GetRuntimeMethod( + "get_Item", + [ + typeof(string), + ] + )!; + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public SqlExpression? Translate( + SqlExpression? instance, + MethodInfo method, + IReadOnlyList arguments, + IDiagnosticsLogger logger) + { + if (method != _methodInfo + || method.DeclaringType != typeof(Dictionary) + || instance?.TypeMapping is not NpgsqlHstoreTypeMapping) + { + return null; + } + + return _sqlExpressionFactory.JsonTraversal(instance, arguments, false, typeof(string), _stringTypeMapping); + } +} diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlMethodCallTranslatorProvider.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlMethodCallTranslatorProvider.cs index 46a19b4b5..c7cb11f32 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlMethodCallTranslatorProvider.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlMethodCallTranslatorProvider.cs @@ -51,6 +51,7 @@ public NpgsqlMethodCallTranslatorProvider( new NpgsqlJsonDomTranslator(typeMappingSource, sqlExpressionFactory, model), new NpgsqlJsonDbFunctionsTranslator(typeMappingSource, sqlExpressionFactory, model), new NpgsqlJsonPocoTranslator(typeMappingSource, sqlExpressionFactory, model), + new NpgsqlHstoreTranslator(typeMappingSource, sqlExpressionFactory, model), new NpgsqlLikeTranslator(sqlExpressionFactory), LTreeTranslator, new NpgsqlMathTranslator(typeMappingSource, sqlExpressionFactory, model),