From ba24cb6959ff75ecd489906186f0583697f0fcdb Mon Sep 17 00:00:00 2001 From: Austin Drenski Date: Thu, 31 May 2018 22:33:37 -0400 Subject: [PATCH] Add hook for IQueryOptimizer Creates Npgsql implementations of `IExpressionFragmentTranslator` and `IQueryOptimizer` to support more complex translations. These classes make it easier to inject new fragment translations and expression rewrites into the EF Core translation process. This is split out from #431. Working examples can be found there. --- .../NpgsqlServiceCollectionExtensions.cs | 2 + .../Query/Internal/NpgsqlQueryOptimizer.cs | 55 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 src/EFCore.PG/Query/Internal/NpgsqlQueryOptimizer.cs diff --git a/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs b/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs index ed9f9619d..58a569d5f 100644 --- a/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs +++ b/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs @@ -30,6 +30,7 @@ using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; using Microsoft.EntityFrameworkCore.Query.ExpressionVisitors; +using Microsoft.EntityFrameworkCore.Query.Internal; using Microsoft.EntityFrameworkCore.Query.Sql; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Update; @@ -113,6 +114,7 @@ public static IServiceCollection AddEntityFrameworkNpgsql([NotNull] this IServic .TryAdd() .TryAdd() .TryAdd() + .TryAdd() .TryAdd() .TryAdd() .TryAdd(p => p.GetService()) diff --git a/src/EFCore.PG/Query/Internal/NpgsqlQueryOptimizer.cs b/src/EFCore.PG/Query/Internal/NpgsqlQueryOptimizer.cs new file mode 100644 index 000000000..df9136e1a --- /dev/null +++ b/src/EFCore.PG/Query/Internal/NpgsqlQueryOptimizer.cs @@ -0,0 +1,55 @@ +#region License + +// The PostgreSQL License +// +// Copyright (C) 2016 The Npgsql Development Team +// +// Permission to use, copy, modify, and distribute this software and its +// documentation for any purpose, without fee, and without a written +// agreement is hereby granted, provided that the above copyright notice +// and this paragraph and the following two paragraphs appear in all copies. +// +// IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY +// FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +// DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF +// THE POSSIBILITY OF SUCH DAMAGE. +// +// THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS +// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +#endregion + +using System.Linq.Expressions; +using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.Query.Internal; +using Remotion.Linq; + +namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal +{ + /// + /// The default relational LINQ query optimizer for Npgsql. + /// + public class NpgsqlQueryOptimizer : QueryOptimizer + { + /// + /// The default expression visitors registered by the Npgsql provider. + /// + [NotNull] [ItemNotNull] static readonly ExpressionVisitor[] ExpressionVisitors = {}; + + /// + public override void Optimize(QueryCompilationContext queryCompilationContext, QueryModel queryModel) + { + base.Optimize(queryCompilationContext, queryModel); + + for (int i = 0; i < ExpressionVisitors.Length; i++) + { + queryModel.TransformExpressions(ExpressionVisitors[i].Visit); + } + } + } +}