Почему я не могу сопоставить массив дочерних элементов с 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; }
}