Я создаю API и хотел бы иметь возможность загружать данные из разных файлов JSON, каждый из которых содержит дерево JSON. Это работало нормально, пока я не столкнулся с отношениями «Родитель / Дети».
Я создал новый проект .NET Core, чтобы попытаться заставить его работать в простом решении с тремя сущностями:
public class Library
{
public int LibraryId { get; set; }
public string Name { get; set; }
public IEnumerable<Book> Books { get; set; }
}
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
public IEnumerable<Chapter> Chapters { get; set; }
}
public class Chapter
{
public int ChapterId { get; set; }
public string Title { get; set; }
public Book Book { get; set; }
public int BookId { get; set; }
public int? ParentChapterId { get; set; }
public Chapter ParentChapter { get; set; }
public IEnumerable<Chapter> ChildrenChapters { get; set; }
}
DbContext:
public DbSet<Library> Libraries { get; set; }
public DbSet<Book> Books { get; set; }
public DbSet<Chapter> Chapters { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Chapter>()
.HasMany(p => p.ChildrenChapters)
.WithOne(p => p.ParentChapter)
.HasForeignKey(p => p.ParentChapterId)
.IsRequired(false);
base.OnModelCreating(builder);
}
Startup.cs:
var dataText = System.IO.File.ReadAllText("Data/JsonSeeding/json.json");
Seeder.SeedFromJson(dataText, app.ApplicationServices);
Seeder.cs
public static class Seeder
{
public static void SeedFromJson(string jsonData, IServiceProvider serviceProvider)
{
List<Library> collection = JsonConvert.DeserializeObject<List<Library>>(jsonData);
using (var serviceScope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope
.ServiceProvider.GetService<BizDbContext>();
if (!context.Libraries.Any())
{
context.AddRange(collection);
context.SaveChanges();
}
}
}
}
И, наконец, файл JSON:
[
{
"Name": "Library_1",
"Books": [
{
"Title": "BookTitle1",
"Chapters": [
{
"Title": "Chapter_1",
"ChildrenChapters": [
{
"Title": "Chapter_1_1",
"ChildrenChapters": [
{
"Title": "Chapter_1_1_1"
},
{
"Title": "Chapter_1_1_1"
},
{
"Title": "Chapter_1_1_1"
}
]
}
]
},
{
"Title": "Chapter_2"
},
{
"Title": "Chapter_3"
}
]
}
]
}
]
Отлично работает при заполнении Библиотеки> Книга> Глава, но не работает при добавлении ChildrenChapters:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Chapters_Books_BookId".
The conflict occurred in database "JSONTreeSeedingTest", table "dbo.Books", column 'BookId'.
Я понимаю ошибку. Есть ли способ по-прежнему использовать тот же формат JSON и определить, что элементы в ChildrenChapters должны иметь тот же BookId, что и ParentChapter?