Skip to content

EF Core global query filter based on nullable property resulting in NullReferenceException #28940

@DaveSenn

Description

@DaveSenn

Description

Queries using the below global filter result in a NullReferenceException.
It looks like EF always evaluates the second condition AllowedTenants.Contains( x.TenantId ) even if the first condition is true.

Include your code

public interface ITest
{
    IReadOnlyCollection<Int64>? GetTenants();
}

public sealed class Temp : IEfTenantProvider
{
    private readonly IArgosAuthorizationService _argosAuthorizationService;

    public IReadOnlyCollection<Int64>? GetTenants() =>
        null;
}

public class MyContextFactory : IDbContextFactory<MyContext>
{
    private readonly IDbContextFactory<MyContext> _pooledFactory;
    private readonly IReadOnlyCollection<Int64>? _allowedTenants;

    public MyContextFactory( IDbContextFactory<MyContext> pooledFactory, ITest tenant)
    {
        _pooledFactory = pooledFactory;
        _allowedTenants = tenant.GetTenants();
    }

    public MyContext CreateDbContext()
    {
        var context = _pooledFactory.CreateDbContext();
        context.AllowedTenants = _allowedTenants;
        return context;
    }
}

public class MyContext : DbContext
{
    public virtual DbSet<SomeTable> SomeTable { get; set; } = null!;

    public MyContext( DbContextOptions<MyContext> options )
        : base( options )
    {
    }

    public IReadOnlyCollection<Int64>? AllowedTenants { get; set; }
    protected override void OnModelCreating( ModelBuilder modelBuilder )
    {
        modelBuilder.Entity<SomeTable>().HasQueryFilter( x => AllowedTenants == null || AllowedTenants.Contains( x.TenantId ) );
    }
}

Include stack traces

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=Microsoft.EntityFrameworkCore.Relational
  StackTrace:
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.<VisitIn>g__ProcessInExpressionValues|29_0(SqlExpression valuesExpression, Boolean extractNullValues)
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.VisitIn(InExpression inExpression, Boolean allowOptimizedExpansion, Boolean& nullable)
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(SqlExpression sqlExpression, Boolean allowOptimizedExpansion, Boolean preserveColumnNullabilityInformation, Boolean& nullable)
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.VisitSqlBinary(SqlBinaryExpression sqlBinaryExpression, Boolean allowOptimizedExpansion, Boolean& nullable)
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(SqlExpression sqlExpression, Boolean allowOptimizedExpansion, Boolean preserveColumnNullabilityInformation, Boolean& nullable)
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(SqlExpression sqlExpression, Boolean allowOptimizedExpansion, Boolean& nullable)
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(SelectExpression selectExpression)
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(TableExpressionBase tableExpressionBase)
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(TableExpressionBase tableExpressionBase)
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(SelectExpression selectExpression)
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(TableExpressionBase tableExpressionBase)
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(TableExpressionBase tableExpressionBase)
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Visit(SelectExpression selectExpression)
   at Microsoft.EntityFrameworkCore.Query.SqlNullabilityProcessor.Process(SelectExpression selectExpression, IReadOnlyDictionary`2 parameterValues, Boolean& canCache)
   at Microsoft.EntityFrameworkCore.Query.RelationalParameterBasedSqlProcessor.Optimize(SelectExpression selectExpression, IReadOnlyDictionary`2 parametersValues, Boolean& canCache)
   at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerParameterBasedSqlProcessor.Optimize(SelectExpression selectExpression, IReadOnlyDictionary`2 parametersValues, Boolean& canCache)
   at Microsoft.EntityFrameworkCore.Query.Internal.RelationalCommandCache.GetRelationalCommandTemplate(IReadOnlyDictionary`2 parameters)
   at Microsoft.EntityFrameworkCore.Internal.RelationCommandCacheExtensions.RentAndPopulateRelationalCommand(RelationalCommandCache relationalCommandCache, RelationalQueryContext queryContext)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.<<PopulateSplitIncludeCollectionAsync>g__InitializeReaderAsync|63_0>d`2.MoveNext()
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.<>c__DisplayClass33_0`2.<<ExecuteAsync>b__0>d.MoveNext()
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.<ExecuteImplementationAsync>d__34`2.MoveNext()
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.<ExecuteImplementationAsync>d__34`2.MoveNext()
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.<ExecuteAsync>d__33`2.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.<PopulateSplitIncludeCollectionAsync>d__63`2.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.<TaskAwaiter>d__69.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable`1.AsyncEnumerator.<MoveNextAsync>d__19.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.<SingleAsync>d__14`1.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.<SingleAsync>d__14`1.MoveNext()

Include provider and version information

EF Core 6.0.8
SQL Server 2019

Microsoft Visual Studio Professional 2022
Version 17.3.2
VisualStudio.17.Release/17.3.2+32819.101
Microsoft .NET Framework
Version 4.8.04084

Installed Version: Professional

Visual C++ 2022 00476-80000-00000-AA450
Microsoft Visual C++ 2022

ASP.NET and Web Tools 17.3.376.3011
ASP.NET and Web Tools

Azure App Service Tools v3.0.0 17.3.376.3011
Azure App Service Tools v3.0.0

Azure Functions and Web Jobs Tools 17.3.376.3011
Azure Functions and Web Jobs Tools

C# Tools 4.3.0-3.22412.4+c97184bafab9a34d61e85f1c1ef34f25283ce9ba
C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Common Azure Tools 1.10
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

Entity Framework Core Power Tools 2.5
Adds useful design-time EF Core DbContext features to the Visual Studio Solution Explorer context menu.

Microsoft JVM Debugger 1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

Node.js Tools 1.5.40629.1 Commit Hash:3f5cc0329815af3ffb948f08857446d206a9af36
Adds support for developing and debugging Node.js apps in Visual Studio

NuGet Package Manager 6.3.0
NuGet Package Manager in Visual Studio. For more information about NuGet, visit https://docs.nuget.org/

Razor (ASP.NET Core) 17.0.0.2232702+e1d654e792aa2fe6646a6935bcca80ff0aff4387
Provides languages services for ASP.NET Core Razor.

SQL Server Data Tools 17.0.62207.04100
Microsoft SQL Server Data Tools

Switch Startup Project 4.2.76
Provides a toolbar dropdown box to switch between startup projects.

Test Adapter for Boost.Test 1.0
Enables Visual Studio's testing tools with unit tests written for Boost.Test. The use terms and Third Party Notices are available in the extension installation directory.

Test Adapter for Google Test 1.0
Enables Visual Studio's testing tools with unit tests written for Google Test. The use terms and Third Party Notices are available in the extension installation directory.

TypeScript Tools 17.0.10701.2001
TypeScript Tools for Microsoft Visual Studio

Visual Basic Tools 4.3.0-3.22412.4+c97184bafab9a34d61e85f1c1ef34f25283ce9ba
Visual Basic components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Visual F# Tools 17.1.0-beta.22363.4+1b94f89d4d1f41f20f9be73c76f4b229d4e49078
Microsoft Visual F# Tools

Visual Studio IntelliCode 2.2
AI-assisted development for Visual Studio.

VsChromium 0.9.39
Collection of tools to help contributing code to the Chromium project.

VSColorOutput64 2022.2
Color output for build and debug windows - https://mike-ward.net/vscoloroutput

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions