Skip to content

System.Text.Json.JsonReaderException on BulkInsertAsync when SetOutputIdentity = true, and IsJson column is null #1572

@manuel-fernandez-rodriguez

Description

Description

BulkInsertAsync bombs out in SQL Server when trying to insert a row with a null value for a column configured as IsJson.

Interestingly, it only dies if you request it to retrieve the identity column value, as shown in the repro steps below.

Seems to be loosely related to #1565

Reproducing the bug

proof.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="EFCore.BulkExtensions" Version="8.1.1" />    
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.8" />
  </ItemGroup>
</Project>

Program.cs

using EFCore.BulkExtensions;
using Microsoft.EntityFrameworkCore;

using var context = new DataContext();

context.Database.EnsureDeleted();
context.Database.EnsureCreated();

await context.BulkInsertAsync([new People() { Name = "John Doe", Address = new() { Street = "1428 Elm St." } }]);
Console.WriteLine("John is saved!");

await context.BulkInsertAsync([new People() { Name = "Jane Homeless", Address = null }]);
Console.WriteLine("Jane is safe, too");

await context.BulkInsertAsync([new People() { Name = "Private Ryan", Address = null }], c => c.SetOutputIdentity = true);
// System.Text.Json.JsonReaderException:
// ''0x00' is invalid after a single JSON value. Expected end of data. LineNumber: 0 | BytePositionInLine: 4.'

Console.WriteLine("Oh, no! we failed at saving Private Ryan!");

public class People {
    public long Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public string Street { get; set; }
}

public class DataContext : DbContext
{
    public DbSet<People> People { get; set; }
    
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) =>
        optionsBuilder.UseSqlServer("REDACTED");

    protected override void OnModelCreating(ModelBuilder modelBuilder) =>
        modelBuilder.Entity<People>().OwnsOne(p => p.Address, p => p.ToJson());
}

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions