Skip to content

Exception thrown when fetching a single entity with jsonb columns #3702

@athagiorgos

Description

@athagiorgos

Description:
I just upgraded to .NET 10.0 from .NET 9.0 and along with it all the NuGet packages to the latest version.
After upgrading, fetching a single entity by Id with jsonb type columns thows the following exception:

System.ArgumentNullException: Value cannot be null. (Parameter 'key')
         at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
         at System.Collections.Generic.Dictionary`2.set_Item(TKey key, TValue value)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.CreateJsonShapers(ITypeBase structuralType, Type clrType, Boolean nullable, ParameterExpression jsonReaderDataParameter, Expression keyValuesParameter, Expression containerEntityExpression, IPropertyBase structuralProperty)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ProcessShaper(Expression shaperExpression, Expression& relationalCommandResolver, IReadOnlyList`1& readerColumns, LambdaExpression& relatedDataLoaders, Int32& collectionId)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitShapedQuery(ShapedQueryExpression shapedQueryExpression)
         at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
         at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutorExpression[TResult](Expression query)
         at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
         at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
         at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
         at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass11_0`1.<ExecuteCore>b__0()
         at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
         at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteCore[TResult](Expression query, Boolean async, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, LambdaExpression expression, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.FirstOrDefaultAsync[TSource](IQueryable`1 source, Expression`1 predicate, CancellationToken cancellationToken)
         at Properties.Infrastructure.Services.PropertiesService.GetPropertyAsync(Int32 id, CancellationToken cancellationToken) in C:\Users\Giorgos\Documents\asp.net_core\services-properties\Properties.Infrastructure\Services\PropertiesService.cs:line 330
         at Properties.Service.Endpoints.PropertiesEndpoints.<>c.<<MapV2PropertiesEndpoints>b__1_4>d.MoveNext() in C:\Users\Giorgos\Documents\asp.net_core\services-properties\Properties.Service\Endpoints\PropertiesEndpoints.cs:line 433
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Http.RequestDelegateFactory.<TaskOfTToValueTaskOfObject>g__ExecuteAwaited|92_0[T](Task`1 task)
         at Properties.Service.EndpointFilters.TokenHeaderValidationFilter.InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next) in C:\Users\Giorgos\Documents\asp.net_core\services-properties\Properties.Service\EndpointFilters\TokenHeaderValidationFilter.cs:line 31
         at Microsoft.AspNetCore.Http.RequestDelegateFactory.<ExecuteValueTaskOfObject>g__ExecuteAwaited|130_0(ValueTask`1 valueTask, HttpContext httpContext, JsonTypeInfo`1 jsonTypeInfo)
         at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
         at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.<Invoke>g__Awaited|10_0(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)

Model

public class Property
{
    private Property(int id, int organizationId, string token, DateTime? sendDate, DateTime? updateDate,
        bool? isSync, int? statusId, int? categoryId, int? subCategoryId, int? aimId, int[]? areaIds,
        int? areaId, int? subAreaId, string? areaGr, string? areaEn, string? subAreaGr, string? subAreaEn,
        string? postalCode, double? latitude, double? longitude, string? customCode, string? customCodeNormalized, 
        double? price, double? sqrMeters, double? pricePerSqrm, double? plotSqrMeters, int? buildingYear, 
        int? renovationYear, int? rooms, int? masterBedrooms, int? bathrooms, int? wc, int? floorId, string? levels, 
        int? totalFloors, int? energyClassId, string? youtubeVideo, string? virtualTour, string? buildingName,
        bool? mapAsCircle, int? totalParkings, int? completionYear, double? taxPercent, string? auctionPercentage, 
        string? auctionInfo, string? auctionOwnership, Title? title, Partner? partner, Office? office, 
        Project? project, List<ProjectProperty>? projectProperties, List<Characteristic>? characteristics,
        List<DistanceFrom>? distancesFrom, List<Parking>? parkings, List<Basement>? basements, List<Image>? images,
        List<AdditionalLanguage>? additionalLanguages, List<Flag>? flags, List<Mandate>? mandates,
        List<Auction>? auctions, List<Floor>? floors, List<FlagRow>? flagRows, bool isProjectPart, bool isProject,
        List<CharacteristicRow>? characteristicRows)
    {
        Id = id;
        OrganizationId = organizationId;
        Token = token;
        SendDate = sendDate is null 
            ? DateTime.UtcNow
            : DateTime.SpecifyKind(sendDate.Value, DateTimeKind.Utc);
        UpdateDate = updateDate is null 
            ? SendDate
            : DateTime.SpecifyKind(updateDate.Value, DateTimeKind.Utc);
        IsSync = isSync;
        StatusId = statusId;
        CategoryId = categoryId;
        SubCategoryId = subCategoryId;
        AimId = aimId;
        Areas = areaIds;
        AreaId = areaId;
        SubAreaId = subAreaId;
        AreaGr = areaGr;
        AreaEn = areaEn;
        SubAreaGr = subAreaGr;
        SubAreaEn = subAreaEn;
        PostalCode = postalCode;
        Latitude = latitude;
        Longitude = longitude;
        CustomCode = customCode;
        CustomCodeNormalized = customCodeNormalized;
        Price = price;
        SqrMeters = sqrMeters;
        PricePerSqrm = pricePerSqrm;
        PlotSqrMeters = plotSqrMeters;
        BuildingYear = buildingYear;
        RenovationYear = renovationYear;
        Rooms = rooms;
        MasterBedrooms = masterBedrooms;
        Bathrooms = bathrooms;
        Wc = wc;
        FloorId = floorId;
        Levels = levels;
        TotalFloors = totalFloors;
        EnergyClassId = energyClassId;
        YoutubeVideo = youtubeVideo;
        VirtualTour = virtualTour;
        BuildingName = buildingName;
        MapAsCircle = mapAsCircle;
        TotalParkings = totalParkings;
        CompletionYear = completionYear;
        TaxPercent = taxPercent;
        AuctionPercentage = auctionPercentage;
        AuctionInfo = auctionInfo;
        AuctionOwnership = auctionOwnership;
        Title = title;
        Partner = partner;
        Office = office;
        Project = project;
        ProjectProperties = projectProperties;
        Characteristics = characteristics;
        DistancesFrom = distancesFrom;
        Parkings = parkings;
        Basements = basements;
        Images = images;
        AdditionalLanguages = additionalLanguages;
        Flags = flags;
        Mandates = mandates;
        Auctions = auctions;
        Floors = floors;
        FlagRows = flagRows;
        IsProjectPart = isProjectPart;
        IsProject = isProject;
        CharacteristicRows = characteristicRows;
    }

    private Property()
    {
    }

    public int Id { get; private set; }
    public int OrganizationId { get; private set; }
    public string Token { get; private set; }
    public DateTime SendDate { get; private set; }
    public DateTime UpdateDate { get; private set; }
    public bool? IsSync { get; private set; }
    public int? StatusId { get; private set; }
    public int? CategoryId { get; private set; }
    public int? SubCategoryId { get; private set; }
    public int? AimId { get; private set; }
    public int[]? Areas { get; private set; }
    public int? AreaId { get; private set; }
    public int? SubAreaId { get; private set; }
    public string? AreaGr { get; private set; }
    public string? AreaEn { get; private set; }
    public string? SubAreaGr { get; private set; }
    public string? SubAreaEn { get; private set; }
    public string? PostalCode { get; private set; }
    public double? Latitude { get; private set; }
    public double? Longitude { get; private set; }
    public string? CustomCode { get; private set; }
    public string? CustomCodeNormalized { get; private set; }
    public double? Price { get; private set; }
    public double? SqrMeters { get; private set; }
    public double? PricePerSqrm { get; private set; }
    public double? PlotSqrMeters { get; private set; }
    public int? BuildingYear { get; private set; }
    public int? RenovationYear { get; private set; }
    public int? Rooms { get; private set; }
    public int? MasterBedrooms { get; private set; }
    public int? Bathrooms { get; private set; }
    public int? Wc { get; private set; }
    public int? FloorId { get; private set; }
    public string? Levels { get; private set; }
    public int? TotalFloors { get; private set; }
    public int? EnergyClassId { get; private set; }
    public string? YoutubeVideo { get; private set; }
    public string? VirtualTour { get; private set; }
    public string? BuildingName { get; private set; }
    public bool? MapAsCircle { get; private set; }
    public int? TotalParkings { get; private set; }
    public int? CompletionYear { get; private set; }
    public double? TaxPercent { get; private set; }
    public string? AuctionPercentage { get; private set; }
    public string? AuctionInfo { get; private set; }
    public string? AuctionOwnership { get; private set; }
    public Title? Title { get; private set; }
    public Partner? Partner { get; private set; }
    public Office? Office { get; private set; }
    public Project? Project { get; private set; }
    public List<ProjectProperty>? ProjectProperties { get; private set; }
    public List<Characteristic>? Characteristics { get; private set; }
    public List<DistanceFrom>? DistancesFrom { get; private set; }
    public List<Parking>? Parkings { get; private set; }
    public List<Basement>? Basements { get; private set; }
    public List<Image>? Images { get; set; }
    public List<AdditionalLanguage>? AdditionalLanguages { get; private set; }
    public List<Flag>? Flags { get; private set; }
    public virtual List<FlagRow>? FlagRows { get; private set; }
    public List<Mandate>? Mandates { get; private set; }
    public List<Auction>? Auctions { get; private set; }
    public List<Floor>? Floors { get; private set; }
    public bool IsProjectPart { get; private set; }
    public bool IsProject { get; private set; }
    public List<CharacteristicRow>? CharacteristicRows { get; private set; }


    public static Property Create(int id, int organizationId, string token, DateTime? sendDate,
        DateTime? updateDate, bool? isSync, int? statusId, int? categoryId, int? subCategoryId, int? aimId,
        int[]? areaIds, int? areaId, int? subAreaId, string? areaGr, string? areaEn, string? subAreaGr,
        string? subAreaEn, string? postalCode, double? latitude, double? longitude, string? customCode, 
        string? customCodeNormalized, double? price, double? sqrMeters, double? pricePerSqrm, double? plotSqrMeters,
        int? buildingYear, int? renovationYear, int? rooms, int? masterBedrooms, int? bathrooms, int? wc, int? floorId,
        string? levels, int? totalFloors, int? energyClassId, string? youtubeVideo, string? virtualTour,
        string? buildingName, bool? mapAsCircle, int? totalParkings, int? completionYear, double? taxPercent,
        string? auctionPercentage, string? auctionInfo, string? auctionOwnership, Title? title, Partner? partner,
        Office? office, Project? project, List<ProjectProperty>? projectProperties,
        List<Characteristic>? characteristics, List<DistanceFrom>? distancesFrom, List<Parking>? parkings,
        List<Basement>? basements, List<Image>? images, List<AdditionalLanguage>? additionalLanguages,
        List<Flag>? flags, List<Mandate>? mandates, List<Auction>? auctions, List<Floor>? floors,
        List<FlagRow>? flagRows, bool isProjectPart, bool isProject, List<CharacteristicRow>? characteristicRows)
    {
        return new Property(id, organizationId, token, sendDate, updateDate, isSync,
            statusId, categoryId, subCategoryId, aimId, areaIds, areaId, subAreaId, areaGr, areaEn,
            subAreaGr, subAreaEn, postalCode, latitude, longitude, customCode, customCodeNormalized,
            price, sqrMeters, pricePerSqrm, plotSqrMeters, buildingYear, renovationYear, rooms, masterBedrooms,
            bathrooms, wc, floorId, levels, totalFloors, energyClassId, youtubeVideo, virtualTour, buildingName,
            mapAsCircle, totalParkings, completionYear, taxPercent, auctionPercentage, auctionInfo, auctionOwnership,
            title, partner, office, project, projectProperties, characteristics, distancesFrom, parkings,
            basements, images, additionalLanguages, flags, mandates, auctions, floors, flagRows,
            isProjectPart, isProject, characteristicRows);
    }

    public void Update(int organizationId, DateTime? updateDate, bool? isSync, int? statusId,
        int? categoryId, int? subCategoryId, int? aimId, int[]? areaIds, int? areaId, int? subAreaId,
        string? areaGr, string? areaEn, string? subAreaGr, string? subAreaEn, string? postalCode,
        double? latitude, double? longitude, string? customCode, string? customCodeNormalized,
        double? price, double? sqrMeters, double? pricePerSqrm, double? plotSqrMeters, int? buildingYear, 
        int? renovationYear, int? rooms, int? masterBedrooms, int? bathrooms, int? wc, int? floorId,
        string? levels, int? totalFloors, int? energyClassId, string? youtubeVideo, string? virtualTour,
        string? buildingName, bool? mapAsCircle, int? totalParkings, int? completionYear,
        double? taxPercent, string? auctionPercentage, string? auctionInfo, string? auctionOwnership, 
        Title? title, Partner? partner, Office? office, Project? project, List<ProjectProperty>? projectProperties,
        List<Characteristic>? characteristics, List<DistanceFrom>? distancesFrom, List<Parking>? parkings,
        List<Basement>? basements, List<Image>? images, List<AdditionalLanguage>? additionalLanguages,
        List<Flag>? flags, List<Mandate>? mandates, List<Auction>? auctions, List<Floor>? floors,
        List<FlagRow>? flagRows, bool isProjectPart, bool isProject, List<CharacteristicRow>? characteristicRows)
    {
        OrganizationId = OrganizationId == 0 
            ? organizationId 
            : OrganizationId;
        UpdateDate = updateDate is null 
            ? UpdateDate 
            : DateTime.SpecifyKind(updateDate.Value, DateTimeKind.Utc);
        IsSync = isSync;
        StatusId = statusId;
        CategoryId = categoryId;
        SubCategoryId = subCategoryId;
        AimId = aimId;
        Areas = areaIds;
        AreaId = areaId;
        SubAreaId = subAreaId;
        AreaGr = areaGr;
        AreaEn = areaEn;
        SubAreaGr = subAreaGr;
        SubAreaEn = subAreaEn;
        PostalCode = postalCode;
        Latitude = latitude;
        Longitude = longitude;
        CustomCode = customCode;
        CustomCodeNormalized = customCodeNormalized; 
        Price = price;
        SqrMeters = sqrMeters;
        PricePerSqrm = pricePerSqrm;
        PlotSqrMeters = plotSqrMeters;
        BuildingYear = buildingYear;
        RenovationYear = renovationYear;
        Rooms = rooms;
        MasterBedrooms = masterBedrooms;
        Bathrooms = bathrooms;
        Wc = wc;
        FloorId = floorId;
        Levels = levels;
        TotalFloors = totalFloors;
        EnergyClassId = energyClassId;
        YoutubeVideo = youtubeVideo;
        VirtualTour = virtualTour;  
        BuildingName = buildingName;
        MapAsCircle = mapAsCircle;
        TotalParkings = totalParkings;
        CompletionYear = completionYear;
        TaxPercent = taxPercent;
        AuctionPercentage = auctionPercentage;
        AuctionInfo = auctionInfo;
        AuctionOwnership = auctionOwnership;
        Title = title;
        Partner = partner;
        Office = office;
        Project = project;
        ProjectProperties = projectProperties;  
        Characteristics = characteristics;
        DistancesFrom = distancesFrom;
        Parkings = parkings;
        Basements = basements;
        Images = images;
        AdditionalLanguages = additionalLanguages;
        Flags = flags;  
        Mandates = mandates;
        Auctions = auctions;
        Floors = floors;
        FlagRows = flagRows;
        IsProjectPart = isProjectPart;
        IsProject = isProject;
        CharacteristicRows = characteristicRows;
    }
    
}

Configuration

internal sealed class PropertyConfiguration : IEntityTypeConfiguration<Property>
{
    public void Configure(EntityTypeBuilder<Property> builder)
    {
        builder.HasKey(x => new {x.Id, x.Token});
        
        builder.Property(x => x.OrganizationId)
            .IsRequired();
        
        builder.Property(x => x.SendDate)
            .IsRequired();
        
        builder.Property(x => x.UpdateDate)
            .IsRequired();
        
        builder.OwnsOne(x => x.Title,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.Title);
        
        builder.OwnsOne(x => x.Partner,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.Partner);
        
        builder.OwnsOne(x => x.Office,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.Office);
        
        builder.OwnsOne(x => x.Project,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.Project);
        
        builder.OwnsMany(x => x.ProjectProperties,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.ProjectProperties);
        
        builder.OwnsMany(x => x.Characteristics,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.Characteristics);
        
        builder.OwnsMany(x => x.DistancesFrom,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                    navigationBuilder.OwnsMany(x => x.Descriptions);
                })
            .Navigation(x => x.DistancesFrom);
        
        builder.OwnsMany(x => x.Parkings,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.Parkings);
        
        builder.OwnsMany(x => x.Basements,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.Basements);
        
        builder.OwnsMany(x => x.Images,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.Images);
        
        builder.OwnsMany(x => x.AdditionalLanguages,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.AdditionalLanguages);
        
        builder.OwnsMany(x => x.Flags,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.Flags);
        
        builder.OwnsMany(x => x.Mandates,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.Mandates);
        
        builder.OwnsMany(x => x.Auctions,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.Auctions);
        
        builder.OwnsMany(x => x.Floors,
                navigationBuilder =>
                {
                    navigationBuilder.ToJson();
                })
            .Navigation(x => x.Floors);
    }
}

Code that breaks

 var property = await _dbContext.Properties
            .AsNoTracking()
            .FirstOrDefaultAsync(x =>
                x.Id == id, cancellationToken);

The same exact code works on previous versions and any other version other than 10.x.x.

Working versions:
.NET: 9.0

NuGet:

  • Npgsql.EntityFrameworkCore.PostgreSQL 9.0.4
  • Microsoft.EntityFrameworkCore 9.0.12

Non-Working versions:
.NET 10.0

NuGet:

  • Npgsql.EntityFrameworkCore.PostgreSQL 10.0.0
  • Microsoft.EntityFrameworkCore 10.0.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions