Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
369 changes: 334 additions & 35 deletions src/EFCore.Jet/Extensions/JetDbFunctionsExtensions.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public static IServiceCollection AddEntityFrameworkJet([NotNull] this IServiceCo
.TryAdd<ISingletonOptions, IJetOptions>(p => p.GetRequiredService<IJetOptions>())
.TryAdd<IQueryCompilationContextFactory, JetQueryCompilationContextFactory>()
.TryAdd<IMethodCallTranslatorProvider, JetMethodCallTranslatorProvider>()
.TryAdd<IAggregateMethodCallTranslatorProvider, JetAggregateMethodCallTranslatorProvider>()
.TryAdd<IMemberTranslatorProvider, JetMemberTranslatorProvider>()
.TryAdd<IQuerySqlGeneratorFactory, JetQuerySqlGeneratorFactory>()
.TryAdd<IRelationalSqlTranslatingExpressionVisitorFactory, JetSqlTranslatingExpressionVisitorFactory>()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Microsoft.EntityFrameworkCore.Query;

namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal;

/// <summary>
/// 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.
/// </summary>
public class JetAggregateMethodCallTranslatorProvider : RelationalAggregateMethodCallTranslatorProvider
{
/// <summary>
/// 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.
/// </summary>
public JetAggregateMethodCallTranslatorProvider(RelationalAggregateMethodCallTranslatorProviderDependencies dependencies)
: base(dependencies)
{
var sqlExpressionFactory = dependencies.SqlExpressionFactory;
var typeMappingSource = dependencies.RelationalTypeMappingSource;

AddTranslators(
[
new JetStatisticsAggregateMethodTranslator(sqlExpressionFactory, typeMappingSource)
]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class JetMethodCallTranslatorProvider : RelationalMethodCallTranslatorPro
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public JetMethodCallTranslatorProvider(
[NotNull] RelationalMethodCallTranslatorProviderDependencies dependencies)
RelationalMethodCallTranslatorProviderDependencies dependencies)
: base(dependencies)
{
var sqlExpressionFactory = (JetSqlExpressionFactory)dependencies.SqlExpressionFactory;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Collections.Generic;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
using Microsoft.EntityFrameworkCore.Storage;

namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal;

/// <summary>
/// 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.
/// </summary>
public class JetStatisticsAggregateMethodTranslator : IAggregateMethodCallTranslator
{
private readonly ISqlExpressionFactory _sqlExpressionFactory;
private readonly RelationalTypeMapping _doubleTypeMapping;

/// <summary>
/// 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.
/// </summary>
public JetStatisticsAggregateMethodTranslator(
ISqlExpressionFactory sqlExpressionFactory,
IRelationalTypeMappingSource typeMappingSource)
{
_sqlExpressionFactory = sqlExpressionFactory;
_doubleTypeMapping = typeMappingSource.FindMapping(typeof(double))!;
}

/// <summary>
/// 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.
/// </summary>
public virtual SqlExpression? Translate(
MethodInfo method,
EnumerableExpression source,
IReadOnlyList<SqlExpression> arguments,
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
{
// Docs: https://docs.microsoft.com/sql/t-sql/functions/aggregate-functions-transact-sql

if (method.DeclaringType != typeof(JetDbFunctionsExtensions)
|| source.Selector is not SqlExpression sqlExpression)
{
return null;
}

var functionName = method.Name switch
{
nameof(JetDbFunctionsExtensions.StandardDeviationSample) => "StDev",
nameof(JetDbFunctionsExtensions.StandardDeviationPopulation) => "StDevP",
nameof(JetDbFunctionsExtensions.VarianceSample) => "Var",
nameof(JetDbFunctionsExtensions.VariancePopulation) => "VarP",
_ => null
};

if (functionName is null)
{
return null;
}

return _sqlExpressionFactory.Function(functionName, [sqlExpression], nullable: true, argumentsPropagateNullability: [false], typeof(double), _doubleTypeMapping);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13060,6 +13060,8 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Sel
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Select_mathf_truncate(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Select_ToString_IndexOf(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Select_ToString_IndexOf(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.StandardDeviation(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.StandardDeviation(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Static_equals_int_compared_to_long(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Static_equals_int_compared_to_long(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Static_equals_nullable_datetime_compared_to_non_nullable(isAsync: False)
Expand Down Expand Up @@ -13194,6 +13196,8 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Tri
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.TrimEnd_without_arguments_in_predicate(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.TrimStart_without_arguments_in_predicate(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.TrimStart_without_arguments_in_predicate(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Variance(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Variance(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Where_DateOnly_FromDateTime(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Where_DateOnly_FromDateTime(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Where_functions_nested(isAsync: False)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14350,6 +14350,8 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Sel
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Select_mathf_truncate(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Select_ToString_IndexOf(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Select_ToString_IndexOf(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.StandardDeviation(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.StandardDeviation(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Static_equals_int_compared_to_long(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Static_equals_int_compared_to_long(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Static_equals_nullable_datetime_compared_to_non_nullable(isAsync: False)
Expand Down Expand Up @@ -14484,6 +14486,8 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Tri
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.TrimEnd_without_arguments_in_predicate(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.TrimStart_without_arguments_in_predicate(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.TrimStart_without_arguments_in_predicate(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Variance(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Variance(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Where_DateOnly_FromDateTime(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Where_DateOnly_FromDateTime(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindFunctionsQueryJetTest.Where_functions_nested(isAsync: False)
Expand Down
Loading