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
3 changes: 2 additions & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"sdk": {
"version": "9.0.100"
"version": "9.0.100",
"rollForward": "latestMinor"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;

namespace EntityFrameworkCore.Projectables.Infrastructure.Internal;

public class CustomConventionSetPlugin : IConventionSetPlugin
{
public ConventionSet ModifyConventions(ConventionSet conventionSet)
{
conventionSet.ModelFinalizingConventions.Add(new ProjectablesExpandQueryFiltersConvention());

return conventionSet;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Linq.Expressions;
using EntityFrameworkCore.Projectables.Extensions;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Metadata.Conventions;

namespace EntityFrameworkCore.Projectables.Infrastructure.Internal;

public class ProjectablesExpandQueryFiltersConvention : IModelFinalizingConvention
{

/// <inheritdoc />
public void ProcessModelFinalizing(
IConventionModelBuilder modelBuilder,
IConventionContext<IConventionModelBuilder> context)
{
foreach (var entityType in modelBuilder.Metadata.GetEntityTypes())
{
var queryFilter = entityType.GetQueryFilter();
if (queryFilter != null)
{
// Expands query filters
entityType.SetQueryFilter(queryFilter.ExpandProjectables() as LambdaExpression);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ static object CreateTargetInstance(IServiceProvider services, ServiceDescriptor
return ActivatorUtilities.GetServiceOrCreateInstance(services, descriptor.ImplementationType!);
}

// Custom convention to handle global query filters, etc
services.AddScoped<IConventionSetPlugin, CustomConventionSetPlugin>();

if (_compatibilityMode is CompatibilityMode.Full)
{
var targetDescriptor = services.FirstOrDefault(x => x.ServiceType == typeof(IQueryCompiler));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
SELECT [t0].[RecordDate]
FROM [User] AS [u]
INNER JOIN (
SELECT [t].[RecordDate], [t].[UserId]
FROM (
SELECT [o0].[RecordDate], [o0].[UserId], ROW_NUMBER() OVER(PARTITION BY [o0].[UserId] ORDER BY [o0].[RecordDate] DESC) AS [row]
FROM [Order] AS [o0]
) AS [t]
WHERE [t].[row] <= 2
) AS [t0] ON [u].[Id] = [t0].[UserId]
WHERE (
SELECT TOP(1) [o].[Id]
FROM [Order] AS [o]
WHERE [u].[Id] = [o].[UserId]
ORDER BY [o].[RecordDate] DESC) > 100
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,17 @@ public Task ProjectOverMethodTakingDbContext()

return Verifier.Verify(query.ToQueryString());
}

[Fact]
public Task ProjectQueryFilters()
{
using var dbContext = new SampleUserWithGlobalQueryFilterDbContext();

var query = dbContext.Set<User>()
.SelectMany(x => x.Last2Orders)
.Select(x => x.RecordDate);

return Verifier.Verify(query.ToQueryString());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using EntityFrameworkCore.Projectables.Infrastructure;
using Microsoft.EntityFrameworkCore;

namespace EntityFrameworkCore.Projectables.FunctionalTests.Helpers
{
public class SampleUserWithGlobalQueryFilterDbContext : SampleDbContext<ComplexModelTests.User>
{
public SampleUserWithGlobalQueryFilterDbContext(CompatibilityMode compatibilityMode = CompatibilityMode.Full) : base(compatibilityMode)
{
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity<ComplexModelTests.User>(b => {
b.HasQueryFilter(u => u.LastOrder.Id > 100);
});
}
}
}