diff --git a/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs b/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs index ee76be5dfb..2025056dcb 100644 --- a/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs +++ b/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs @@ -51,6 +51,7 @@ // ReSharper disable once CheckNamespace namespace Microsoft.Extensions.DependencyInjection { + // ReSharper disable once UnusedMember.Global public static class NpgsqlEntityFrameworkServicesBuilderExtensions { /// @@ -106,6 +107,8 @@ public static IServiceCollection AddEntityFrameworkNpgsql([NotNull] this IServic .TryAdd() .TryAdd() .TryAdd() + .TryAdd() + .TryAdd() .TryAdd() .TryAdd() .TryAdd(p => p.GetService()) diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCompositeExpressionFragmentTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCompositeExpressionFragmentTranslator.cs new file mode 100644 index 0000000000..e5a684dd03 --- /dev/null +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCompositeExpressionFragmentTranslator.cs @@ -0,0 +1,58 @@ +#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.Collections.Generic; +using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; + +namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Internal +{ + /// + /// A composite expression fragment translator that dispatches to multiple specialized translators specific to Npgsql. + /// + public class NpgsqlCompositeExpressionFragmentTranslator : RelationalCompositeExpressionFragmentTranslator + { + /// + /// The default expression fragment translators registered by the Npgsql provider. + /// + [NotNull] [ItemNotNull] static readonly IExpressionFragmentTranslator[] ExpressionFragmentTranslators = {}; + + /// + public NpgsqlCompositeExpressionFragmentTranslator( + [NotNull] RelationalCompositeExpressionFragmentTranslatorDependencies dependencies) + : base(dependencies) + { + // ReSharper disable once DoNotCallOverridableMethodsInConstructor + AddTranslators(ExpressionFragmentTranslators); + } + + /// + /// Adds additional dispatches to the translators list. + /// + /// The translators. + public new virtual void AddTranslators([NotNull] IEnumerable translators) + => base.AddTranslators(translators); + } +} diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCompositeMemberTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCompositeMemberTranslator.cs index 0e14630d4a..ff4dabdc61 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCompositeMemberTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCompositeMemberTranslator.cs @@ -1,4 +1,5 @@ #region License + // The PostgreSQL License // // Copyright (C) 2016 The Npgsql Development Team @@ -19,6 +20,7 @@ // 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.Collections.Generic; @@ -28,23 +30,37 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Internal { + /// + /// A composite member translator that dispatches to multiple specialized member translators specific to Npgsql. + /// public class NpgsqlCompositeMemberTranslator : RelationalCompositeMemberTranslator { + /// + /// The default member translators registered by the Npgsql provider. + /// + [NotNull] [ItemNotNull] static readonly IMemberTranslator[] MemberTranslators = + { + new NpgsqlStringLengthTranslator(), + new NpgsqlDateTimeMemberTranslator() + }; + + /// public NpgsqlCompositeMemberTranslator( [NotNull] RelationalCompositeMemberTranslatorDependencies dependencies, [NotNull] INpgsqlOptions npgsqlOptions) : base(dependencies) { - AddTranslators(new List - { - new NpgsqlStringLengthTranslator(), - new NpgsqlDateTimeMemberTranslator() - }); + // ReSharper disable once VirtualMemberCallInConstructor + AddTranslators(MemberTranslators); foreach (var plugin in npgsqlOptions.Plugins) plugin.AddMemberTranslators(this); } + /// + /// Adds additional dispatches to the translators list. + /// + /// The translators. public new virtual void AddTranslators([NotNull] IEnumerable translators) => base.AddTranslators(translators); } diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCompositeMethodCallTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCompositeMethodCallTranslator.cs index 5935a105d5..e51eff11b1 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCompositeMethodCallTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCompositeMethodCallTranslator.cs @@ -1,4 +1,5 @@ #region License + // The PostgreSQL License // // Copyright (C) 2016 The Npgsql Development Team @@ -19,6 +20,7 @@ // 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.Collections.Generic; @@ -28,9 +30,15 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Internal { + /// + /// A composite method call translator that dispatches to multiple specialized method call translators specific to Npgsql. + /// public class NpgsqlCompositeMethodCallTranslator : RelationalCompositeMethodCallTranslator { - static readonly IMethodCallTranslator[] _methodCallTranslators = + /// + /// The default method call translators registered by the Npgsql provider. + /// + [NotNull] [ItemNotNull] static readonly IMethodCallTranslator[] MethodCallTranslators = { new NpgsqlArraySequenceEqualTranslator(), new NpgsqlConvertTranslator(), @@ -55,18 +63,23 @@ public class NpgsqlCompositeMethodCallTranslator : RelationalCompositeMethodCall new NpgsqlRangeTranslator() }; + /// public NpgsqlCompositeMethodCallTranslator( [NotNull] RelationalCompositeMethodCallTranslatorDependencies dependencies, [NotNull] INpgsqlOptions npgsqlOptions) : base(dependencies) { // ReSharper disable once DoNotCallOverridableMethodsInConstructor - AddTranslators(_methodCallTranslators); + AddTranslators(MethodCallTranslators); foreach (var plugin in npgsqlOptions.Plugins) plugin.AddMethodCallTranslators(this); } + /// + /// Adds additional dispatches to the translators list. + /// + /// The translators. public new virtual void AddTranslators([NotNull] IEnumerable translators) => base.AddTranslators(translators); } diff --git a/src/EFCore.PG/Query/Internal/NpgsqlQueryOptimizer.cs b/src/EFCore.PG/Query/Internal/NpgsqlQueryOptimizer.cs new file mode 100644 index 0000000000..df9136e1a4 --- /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); + } + } + } +}