Skip to content

Commit

Permalink
Merge branch 'releases/7.x.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
PawelGerr committed Oct 21, 2023
2 parents f31080f + 38cf22d commit 84d95e3
Show file tree
Hide file tree
Showing 40 changed files with 4,054 additions and 261 deletions.
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Use the [repo on GitHub](https://github.com/PawelGerr/Thinktecture.EntityFramewo

## Features
* [Collection Parameters (temp-tables *light*)](https://dev.azure.com/pawelgerr/Thinktecture.EntityFrameworkCore/_wiki/wikis/Thinktecture.EntityFrameworkCore.wiki/109/Collection-Parameters-(temp-tables-light)) (SQL Server)
* [RowNumber Support](https://dev.azure.com/pawelgerr/Thinktecture.EntityFrameworkCore/_wiki/wikis/Thinktecture.EntityFrameworkCore.wiki/14/RowNumber-Support)
* [Window Functions Support (RowNumber, Sum, Average, Min, Max)](https://dev.azure.com/pawelgerr/Thinktecture.EntityFrameworkCore/_wiki/wikis/Thinktecture.EntityFrameworkCore.wiki?wikiVersion=GBwikiMaster&pagePath=/Features/Window%20Functions%20Support%20(RowNumber%2C%20Sum%2C%20Average%2C%20Min%2C%20Max)&pageId=14&_a=edit)
* [Nested (virtual) Transactions](https://dev.azure.com/pawelgerr/Thinktecture.EntityFrameworkCore/_wiki/wikis/Thinktecture.EntityFrameworkCore.wiki/40/Nested-(virtual)-Transactions)
* [Table Hints](https://dev.azure.com/pawelgerr/Thinktecture.EntityFrameworkCore/_wiki/wikis/Thinktecture.EntityFrameworkCore.wiki/71/Table-Hints-(SQL-Server)) (SQL Server)
* [Queries accross multiple databases](https://dev.azure.com/pawelgerr/Thinktecture.EntityFrameworkCore/_wiki/wikis/Thinktecture.EntityFrameworkCore.wiki/43/Queries-accross-multiple-databases) (SQL Server)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public IServiceProvider CreateServiceProvider(string? schema = null)
if (schema != null)
sqlOptions.MigrationsHistoryTable("__EFMigrationsHistory", schema);

sqlOptions.AddRowNumberSupport()
sqlOptions.AddWindowFunctionsSupport()
.AddTenantDatabaseSupport<DemoTenantDatabaseProviderFactory>()
.AddBulkOperationSupport()
.AddCollectionParameterSupport()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public IServiceProvider CreateServiceProvider()
.UseSqlite(ConnectionString, sqlOptions =>
{
sqlOptions.AddBulkOperationSupport()
.AddRowNumberSupport();
.AddWindowFunctionsSupport();
})
.EnableSensitiveDataLogging()
.UseLoggerFactory(_loggerFactory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ public IRelationalDbContextComponentDecorator ComponentDecorator
public bool AddNestedTransactionsSupport { get; set; }

/// <summary>
/// Enables and disables support for "RowNumber".
/// Enables and disables support for windows functions like "RowNumber".
/// </summary>
public bool AddRowNumberSupport { get; set; }
public bool AddWindowFunctionsSupport { get; set; }

/// <summary>
/// Enables and disables support for 'tenant database support'.
Expand Down Expand Up @@ -253,8 +253,8 @@ private string CreateLogFragment()
if (_extension.AddNestedTransactionsSupport)
sb.Append("NestedTransactionsSupport ");

if (_extension.AddRowNumberSupport)
sb.Append("RowNumberSupport ");
if (_extension.AddWindowFunctionsSupport)
sb.Append("WindowFunctionsSupport ");

if (_extension.AddTenantDatabaseSupport)
sb.Append("TenantDatabaseSupport ");
Expand All @@ -278,7 +278,7 @@ public override int GetServiceProviderHashCode()
hashCode.Add(_extension.AddSchemaRespectingComponents);
hashCode.Add(_extension.AddNestedTransactionsSupport);
hashCode.Add(_extension.AddTenantDatabaseSupport);
hashCode.Add(_extension.AddRowNumberSupport);
hashCode.Add(_extension.AddWindowFunctionsSupport);
hashCode.Add(_extension.ComponentDecorator);
hashCode.Add(_extension._stringBuilderPolicy.InitialCapacity);
hashCode.Add(_extension._stringBuilderPolicy.MaximumRetainedCapacity);
Expand All @@ -302,7 +302,7 @@ public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo
&& _extension.AddSchemaRespectingComponents == otherRelationalInfo._extension.AddSchemaRespectingComponents
&& _extension.AddNestedTransactionsSupport == otherRelationalInfo._extension.AddNestedTransactionsSupport
&& _extension.AddTenantDatabaseSupport == otherRelationalInfo._extension.AddTenantDatabaseSupport
&& _extension.AddRowNumberSupport == otherRelationalInfo._extension.AddRowNumberSupport
&& _extension.AddWindowFunctionsSupport == otherRelationalInfo._extension.AddWindowFunctionsSupport
&& _extension._stringBuilderPolicy.InitialCapacity == otherRelationalInfo._extension._stringBuilderPolicy.InitialCapacity
&& _extension._stringBuilderPolicy.MaximumRetainedCapacity == otherRelationalInfo._extension._stringBuilderPolicy.MaximumRetainedCapacity
&& _extension.ComponentDecorator.Equals(otherRelationalInfo._extension.ComponentDecorator);
Expand Down Expand Up @@ -364,7 +364,7 @@ public override void PopulateDebugInfo(IDictionary<string, string> debugInfo)
debugInfo["Thinktecture:CustomRelationalQueryContextFactory"] = _extension.UseThinktectureRelationalQueryContextFactory.ToString(CultureInfo.InvariantCulture);
debugInfo["Thinktecture:SchemaRespectingComponents"] = _extension.AddSchemaRespectingComponents.ToString(CultureInfo.InvariantCulture);
debugInfo["Thinktecture:NestedTransactionsSupport"] = _extension.AddNestedTransactionsSupport.ToString(CultureInfo.InvariantCulture);
debugInfo["Thinktecture:RowNumberSupport"] = _extension.AddRowNumberSupport.ToString(CultureInfo.InvariantCulture);
debugInfo["Thinktecture:WindowFunctionsSupport"] = _extension.AddWindowFunctionsSupport.ToString(CultureInfo.InvariantCulture);
debugInfo["Thinktecture:TenantDatabaseSupport"] = _extension.AddTenantDatabaseSupport.ToString(CultureInfo.InvariantCulture);
debugInfo["Thinktecture:EvaluatableExpressionFilterPlugins"] = String.Join(", ", _extension._evaluatableExpressionFilterPlugins.Select(t => t.ShortDisplayName()));
debugInfo["Thinktecture:ServiceDescriptors"] = String.Join(", ", _extension._serviceDescriptors);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ namespace Thinktecture.EntityFrameworkCore.Infrastructure;
public class RelationalDbContextOptionsExtensionOptions : ISingletonOptions
{
/// <summary>
/// Indication whether the support for "RowNumber" is enabled or not.
/// Indication whether the support for windows functions is enabled or not.
/// </summary>
public bool RowNumberSupportEnabled { get; private set; }
public bool WindowFunctionsSupportEnabled { get; private set; }

/// <summary>
/// Indication whether the 'tenant database support' is enabled or not.
Expand All @@ -23,7 +23,7 @@ public void Initialize(IDbContextOptions options)
{
var extension = GetExtension(options);

RowNumberSupportEnabled = extension.AddRowNumberSupport;
WindowFunctionsSupportEnabled = extension.AddWindowFunctionsSupport;
TenantDatabaseSupportEnabled = extension.AddTenantDatabaseSupport;
}

Expand All @@ -32,8 +32,8 @@ public void Validate(IDbContextOptions options)
{
var extension = GetExtension(options);

if (extension.AddRowNumberSupport != RowNumberSupportEnabled)
throw new InvalidOperationException($"The setting '{nameof(RelationalDbContextOptionsExtension.AddRowNumberSupport)}' has been changed.");
if (extension.AddWindowFunctionsSupport != WindowFunctionsSupportEnabled)
throw new InvalidOperationException($"The setting '{nameof(RelationalDbContextOptionsExtension.AddWindowFunctionsSupport)}' has been changed.");

if (extension.AddTenantDatabaseSupport != TenantDatabaseSupportEnabled)
throw new InvalidOperationException($"The setting '{nameof(RelationalDbContextOptionsExtension.AddTenantDatabaseSupport)}' has been changed.");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,67 +1,67 @@
using System.Reflection;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
using Microsoft.EntityFrameworkCore.Storage;
using Thinktecture.EntityFrameworkCore.Query.SqlExpressions;

namespace Thinktecture.EntityFrameworkCore.Query.ExpressionTranslators;

/// <summary>
/// Translated extension method "RowNumber"
/// </summary>
public sealed class RowNumberTranslator : IMethodCallTranslator
{
private readonly ISqlExpressionFactory _sqlExpressionFactory;

internal RowNumberTranslator(ISqlExpressionFactory sqlExpressionFactory)
{
_sqlExpressionFactory = sqlExpressionFactory;
}

/// <inheritdoc />
public SqlExpression? Translate(
SqlExpression? instance,
MethodInfo method,
IReadOnlyList<SqlExpression> arguments,
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
{
ArgumentNullException.ThrowIfNull(method);
ArgumentNullException.ThrowIfNull(arguments);

if (method.DeclaringType != typeof(RelationalDbFunctionsExtensions))
return null;

switch (method.Name)
{
case nameof(RelationalDbFunctionsExtensions.OrderBy):
{
var orderBy = arguments.Skip(1).Select(e => new OrderingExpression(_sqlExpressionFactory.ApplyDefaultTypeMapping(e), true)).ToList();
return new RowNumberClauseOrderingsExpression(orderBy);
}
case nameof(RelationalDbFunctionsExtensions.OrderByDescending):
{
var orderBy = arguments.Skip(1).Select(e => new OrderingExpression(_sqlExpressionFactory.ApplyDefaultTypeMapping(e), false)).ToList();
return new RowNumberClauseOrderingsExpression(orderBy);
}
case nameof(RelationalDbFunctionsExtensions.ThenBy):
{
var orderBy = arguments.Skip(1).Select(e => new OrderingExpression(_sqlExpressionFactory.ApplyDefaultTypeMapping(e), true));
return ((RowNumberClauseOrderingsExpression)arguments[0]).AddColumns(orderBy);
}
case nameof(RelationalDbFunctionsExtensions.ThenByDescending):
{
var orderBy = arguments.Skip(1).Select(e => new OrderingExpression(_sqlExpressionFactory.ApplyDefaultTypeMapping(e), false));
return ((RowNumberClauseOrderingsExpression)arguments[0]).AddColumns(orderBy);
}
case nameof(RelationalDbFunctionsExtensions.RowNumber):
{
var partitionBy = arguments.Skip(1).Take(arguments.Count - 2).Select(e => _sqlExpressionFactory.ApplyDefaultTypeMapping(e)).ToList();
var orderings = (RowNumberClauseOrderingsExpression)arguments[^1];
return new RowNumberExpression(partitionBy, orderings.Orderings, RelationalTypeMapping.NullMapping);
}
default:
throw new InvalidOperationException($"Unexpected method '{method.Name}' in '{nameof(RelationalDbFunctionsExtensions)}'.");
}
}
}
using System.Reflection;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
using Microsoft.EntityFrameworkCore.Storage;
using Thinktecture.EntityFrameworkCore.Query.SqlExpressions;

namespace Thinktecture.EntityFrameworkCore.Query.ExpressionTranslators;

/// <summary>
/// Translates extension methods like "RowNumber"
/// </summary>
public sealed class RelationalDbFunctionsTranslator : IMethodCallTranslator
{
private readonly ISqlExpressionFactory _sqlExpressionFactory;

internal RelationalDbFunctionsTranslator(ISqlExpressionFactory sqlExpressionFactory)
{
_sqlExpressionFactory = sqlExpressionFactory;
}

/// <inheritdoc />
public SqlExpression? Translate(
SqlExpression? instance,
MethodInfo method,
IReadOnlyList<SqlExpression> arguments,
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
{
ArgumentNullException.ThrowIfNull(method);
ArgumentNullException.ThrowIfNull(arguments);

if (method.DeclaringType != typeof(RelationalDbFunctionsExtensions))
return null;

switch (method.Name)
{
case nameof(RelationalDbFunctionsExtensions.OrderBy):
{
var orderBy = arguments.Skip(1).Select(e => new OrderingExpression(_sqlExpressionFactory.ApplyDefaultTypeMapping(e), true)).ToList();
return new WindowFunctionOrderingsExpression(orderBy);
}
case nameof(RelationalDbFunctionsExtensions.OrderByDescending):
{
var orderBy = arguments.Skip(1).Select(e => new OrderingExpression(_sqlExpressionFactory.ApplyDefaultTypeMapping(e), false)).ToList();
return new WindowFunctionOrderingsExpression(orderBy);
}
case nameof(RelationalDbFunctionsExtensions.ThenBy):
{
var orderBy = arguments.Skip(1).Select(e => new OrderingExpression(_sqlExpressionFactory.ApplyDefaultTypeMapping(e), true));
return ((WindowFunctionOrderingsExpression)arguments[0]).AddColumns(orderBy);
}
case nameof(RelationalDbFunctionsExtensions.ThenByDescending):
{
var orderBy = arguments.Skip(1).Select(e => new OrderingExpression(_sqlExpressionFactory.ApplyDefaultTypeMapping(e), false));
return ((WindowFunctionOrderingsExpression)arguments[0]).AddColumns(orderBy);
}
case nameof(RelationalDbFunctionsExtensions.RowNumber):
{
var partitionBy = arguments.Skip(1).Take(arguments.Count - 2).Select(e => _sqlExpressionFactory.ApplyDefaultTypeMapping(e)).ToList();
var orderings = (WindowFunctionOrderingsExpression)arguments[^1];
return new RowNumberExpression(partitionBy, orderings.Orderings, RelationalTypeMapping.NullMapping);
}
default:
throw new InvalidOperationException($"Unexpected method '{method.Name}' in '{nameof(RelationalDbFunctionsExtensions)}'.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public RelationalMethodCallTranslatorPlugin(RelationalDbContextOptionsExtensionO

var translators = new List<IMethodCallTranslator>();

if (options.RowNumberSupportEnabled)
translators.Add(new RowNumberTranslator(sqlExpressionFactory));
if (options.WindowFunctionsSupportEnabled)
translators.Add(new RelationalDbFunctionsTranslator(sqlExpressionFactory));

Translators = translators;
}
Expand Down
Loading

0 comments on commit 84d95e3

Please sign in to comment.