Почему я не могу сопоставить массив дочерних элементов с JSON?

Мой код (предварительная версия .NET 8.0 6), позволяющий разрешитьToJson()в SQLite:

      using Microsoft.EntityFrameworkCore;

var ctx = new TestContext();
ctx.Database.EnsureCreated();
ctx.Items.ToArray();

class TestContext : DbContext
{
    public DbSet<TestItem> Items { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=test.db");
        base.OnConfiguring(optionsBuilder);
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<TestItem>().OwnsMany(ti => ti.Children, builder => builder.ToJson());
    }
}

class TestItem
{
    public required int Id { get; set; }
    public required string Name { get; set; }
    public required List<TestChild> Children { get; set; }
}

class TestChild
{
    public required int Id { get; set; }
    public required string Name { get; set; }
}
      <Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0-preview.6.23329.4" />
  </ItemGroup>

</Project>

При загрузке (пустой) таблицы элементов я получаю следующую ошибку:

Выброшено исключение: «System.ArgumentException» в System.Linq.Expressions.dll. В System.Linq.Expressions.dll произошло необработанное исключение типа «System.ArgumentException». Выражение типа «System.Object» не может быть использовано для присвоения типу. 'Система.Int32'

Кажется, это связано со списком детей. Я могу сделать аналогичную модель с одним ребенком (вместо детей), и это работает. На данный момент база данных пуста, поэтому речь не идет о загруженном содержимом данных.

1 ответ

Проблема в собственностиTestChild. Существуют некоторые соглашения относительно свойств, названных или имеющих суффиксId(например, они обнаруживаются как PK). Если вы измените тип столбца наstringи попробуйте сохранить и прочитать данные из столбца, вы получите сообщение с описанием проблемы:

System.InvalidOperationException: тип сущности «TestChild» является частью коллекции, сопоставленной с JSON, и ее порядковый ключ определен явно. Поддерживаются только неявно определенные порядковые ключи.

Переименуйте столбец во что-то вродеIdentifiactor:

      class TestChild
{
    public required int Identifiactor { get; set; }
    public required string Name { get; set; }
}

Также проверьте, что столбцы с именем «Id» в объекте JSon вызывают исключение System.ArgumentException в проблеме материализации в github:

Собственные типы, являющиеся частью коллекции, имеют жестко закодированный порядковый ключ с именем «Id» типа int.

Обратите внимание, что в качестве обходного пути вы можете использоватьJsonPropertyNameатрибут (который, похоже, игнорируется EF Core):

      class TestChild
{
    [JsonPropertyName("Id")]
    public required int SomeInt { get; set; }
    public required string Name { get; set; }
}
Другие вопросы по тегам