Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding regression test for #18510 - InvalidOperationException : When called from 'VisitLambda', rewriting a node of type 'System.Linq.Expressions.ParameterExpression' must return a non-null value of the same type. #21849

Merged
1 commit merged into from
Jul 30, 2020
Merged
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
95 changes: 95 additions & 0 deletions test/EFCore.SqlServer.FunctionalTests/Query/QueryBugsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8103,6 +8103,101 @@ private SqlServerTestStore CreateDatabase19206()

#endregion


#region Issue 18510

[ConditionalFact]
public virtual void Invoke_inside_query_filter_gets_correctly_evaluated_during_translation()
{
using (CreateDatabase18510())
{
using var context = new MyContext18510(_options);

context.TenantId = 1;
var query1 = context.Entities.ToList();
Assert.True(query1.All(x => x.TenantId == 1));

context.TenantId = 2;
var query2 = context.Entities.ToList();
Assert.True(query2.All(x => x.TenantId == 2));

AssertSql(
@"@__ef_filter__p_0='1'

SELECT [e].[Id], [e].[Name], [e].[TenantId]
FROM [Entities] AS [e]
WHERE (([e].[Name] <> N'Foo') OR [e].[Name] IS NULL) AND ([e].[TenantId] = @__ef_filter__p_0)",
//
@"@__ef_filter__p_0='2'

SELECT [e].[Id], [e].[Name], [e].[TenantId]
FROM [Entities] AS [e]
WHERE (([e].[Name] <> N'Foo') OR [e].[Name] IS NULL) AND ([e].[TenantId] = @__ef_filter__p_0)");
}
}

public class MyEntity18510
{
public int Id { get; set; }
public string Name { get; set; }

public int TenantId { get; set; }
}

private class MyContext18510 : DbContext
{
public DbSet<MyEntity18510> Entities { get; set; }

public int TenantId { get; set; }

public MyContext18510(DbContextOptions options)
: base(options)
{
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity18510>().HasQueryFilter(x => x.Name != "Foo");

var entityType = modelBuilder.Model.GetEntityTypes().Single(et => et.ClrType == typeof(MyEntity18510));
var queryFilter = entityType.GetQueryFilter();
Expression<Func<int>> tenantFunc = () => TenantId;
var tenant = Expression.Invoke(tenantFunc);

var efPropertyMethod = typeof(EF).GetTypeInfo().GetDeclaredMethod(nameof(EF.Property)).MakeGenericMethod(typeof(int));
var prm = queryFilter.Parameters[0];
var efPropertyMethodCall = Expression.Call(efPropertyMethod, prm, Expression.Constant("TenantId"));

var updatedQueryFilter = Expression.Lambda(
Expression.AndAlso(
queryFilter.Body,
Expression.Equal(
efPropertyMethodCall,
tenant)),
prm);

entityType.SetQueryFilter(updatedQueryFilter);
}
}

private SqlServerTestStore CreateDatabase18510()
=> CreateTestStore(
() => new MyContext18510(_options),
context =>
{
var e1 = new MyEntity18510 { Name = "e1", TenantId = 1 };
var e2 = new MyEntity18510 { Name = "e2", TenantId = 2 };
var e3 = new MyEntity18510 { Name = "e3", TenantId = 2 };
var e4 = new MyEntity18510 { Name = "Foo", TenantId = 2 };

context.Entities.AddRange(e1, e2, e3, e4);
context.SaveChanges();

ClearLog();
});

#endregion

private DbContextOptions _options;

private SqlServerTestStore CreateTestStore<TContext>(
Expand Down