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
20 changes: 19 additions & 1 deletion src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ public class ExpressionTreeFuncletizer : ExpressionVisitor
private static readonly bool UseOldBehavior37974 =
AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue37974", out var enabled37974) && enabled37974;

private static readonly bool UseOldBehavior38132 =
AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue38132", out var enabled38132) && enabled38132;

// The general algorithm here is the following.
// 1. First, for each node type, visit that node's children and get their states (evaluatable, contains evaluatable, no evaluatable).
// 2. Calculate the parent node's aggregate state from its children; a container node whose children are all evaluatable is itself
Expand Down Expand Up @@ -2129,6 +2132,19 @@ bool PreserveConvertNode(Expression expression)
}
}

if (!UseOldBehavior38132)
{
// As a safety guard, if there's any problematic character in the name for any reason, fall back to "p".
foreach (var c in parameterName)
{
if (!char.IsLetterOrDigit(c) && c != '_')
{
parameterName = "p";
break;
}
}
}

if (UseOldBehavior37152)
{
// Uniquify the parameter name
Expand Down Expand Up @@ -2169,7 +2185,9 @@ bool PreserveConvertNode(Expression expression)
if (visited != expression)
{
parameterName = QueryFilterPrefix
+ (RemoveConvert(expression) is MemberExpression { Member.Name: var memberName } ? ("__" + memberName) : "__p");
+ (RemoveConvert(expression) is MemberExpression { Member.Name: var memberName }
? "__" + (UseOldBehavior38132 ? memberName : SanitizeCompilerGeneratedName(memberName))
: "__p");
isContextAccessor = true;

// Context accessors (query filters accessing the context) never get constantized
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -815,4 +815,39 @@ public class FooBar35111
}

#endregion

#region 38132

[ConditionalFact]
public virtual async Task Query_filter_with_primary_constructor_parameter()
{
Comment thread
roji marked this conversation as resolved.
var contextFactory = await InitializeAsync<Context38132>(
addServices: s =>
{
s.AddSingleton(typeof(Guid),
new Guid("00000001-0000-0000-0000-000000000001"));
return s;
},
usePooling: false);
using var context = contextFactory.CreateContext();

var result = context.Set<Entity38132>().ToList();
Assert.Empty(result);
}

protected class Context38132(DbContextOptions options, Guid tenantId) : DbContext(options)
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
=> modelBuilder.Entity<Entity38132>()
.HasQueryFilter(e => e.TenantId == tenantId);
}

public class Entity38132
{
public int Id { get; set; }
public string Name { get; set; }
public Guid TenantId { get; set; }
}

#endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,20 @@ FROM [Locations] AS [l]
) AS [l0] ON [s].[LocationId] = [l0].[LocationId]
WHERE [s].[IsDeleted] = 0
ORDER BY [s].[Name]
""");
}

public override async Task Query_filter_with_primary_constructor_parameter()
{
await base.Query_filter_with_primary_constructor_parameter();

AssertSql(
"""
@ef_filter__tenantId='00000001-0000-0000-0000-000000000001'

SELECT [e].[Id], [e].[Name], [e].[TenantId]
FROM [Entity38132] AS [e]
WHERE [e].[TenantId] = @ef_filter__tenantId
""");
}
}
Loading