Skip to content

Commit

Permalink
Add hook for IQueryOptimizer
Browse files Browse the repository at this point in the history
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 npgsql#431. Working examples can be found there.
  • Loading branch information
austindrenski committed Jul 25, 2018
1 parent 888dfed commit ba24cb6
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -113,6 +114,7 @@ public static IServiceCollection AddEntityFrameworkNpgsql([NotNull] this IServic
.TryAdd<IMemberTranslator, NpgsqlCompositeMemberTranslator>()
.TryAdd<ICompositeMethodCallTranslator, NpgsqlCompositeMethodCallTranslator>()
.TryAdd<IExpressionFragmentTranslator, NpgsqlCompositeExpressionFragmentTranslator>()
.TryAdd<IQueryOptimizer, NpgsqlQueryOptimizer>()
.TryAdd<IQuerySqlGeneratorFactory, NpgsqlQuerySqlGeneratorFactory>()
.TryAdd<ISqlTranslatingExpressionVisitorFactory, NpgsqlSqlTranslatingExpressionVisitorFactory>()
.TryAdd<ISingletonOptions, INpgsqlOptions>(p => p.GetService<INpgsqlOptions>())
Expand Down
55 changes: 55 additions & 0 deletions src/EFCore.PG/Query/Internal/NpgsqlQueryOptimizer.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// The default relational LINQ query optimizer for Npgsql.
/// </summary>
public class NpgsqlQueryOptimizer : QueryOptimizer
{
/// <summary>
/// The default expression visitors registered by the Npgsql provider.
/// </summary>
[NotNull] [ItemNotNull] static readonly ExpressionVisitor[] ExpressionVisitors = {};

/// <inheritdoc />
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);
}
}
}
}

0 comments on commit ba24cb6

Please sign in to comment.