#c# #asp.net-core #entity-framework-core
Вопрос:
Я использую ASP.NET Основной веб-API с .NET 5 и Entity Framework Core 5.
У меня есть таблица Article
с некоторыми свойствами, и я пытаюсь понять, что статья может содержать другие статьи. Как иерархия или какой-то «Перечень материалов».
Я не хочу создавать дополнительные таблицы, например SubArticle
, потому что они могут быть вложены несколько раз.
Я думал о создании таблицы сопоставления ArticleHierarchy
, которая также используется для отношений M2M, но только с одной таблицей, возможно ли это?
public class Article { [Key] public int Id { get; set; } public string Name{ get; set; } public string SomeProperties { get; set; } public virtual ICollectionlt;ArticleHierarchygt; ArticleHierarchies { get; set; } } public class ArticleHierarchy { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [ForeignKey(nameof(ParentArticle))] public int ArticleParentId { get; set; } [ForeignKey(nameof(ChildArticle))] public int ArticleChildId { get; set; } public virtual Article ParentArticle { get; set; } public virtual Article ChildArticle { get; set; } }
Это правильный путь, и если да, то как должны выглядеть мои занятия?
Или есть еще лучший способ сделать это?
Спасибо
Ответ №1:
вы должны исправить отношения, добавить
public class Article { [Key] public int Id { get; set; } public string Name{ get; set; } public string SomeProperties { get; set; } [InverseProperty(nameof(ArticleHierarchy.ChildArticle))] public virtual ICollectionlt;ArticleHierarchygt; ChildArticleHierarchies { get; set; } [InverseProperty(nameof(ArticleHierarchy.ParentArticle))] public virtual ICollectionlt;ArticleHierarchygt; ParentArticleHierarchies { get; set;} } public class ArticleHierarchy { [Key] public int Id { get; set; } public int ArticleParentId { get; set; } public int ArticleChildId { get; set; } [ForeignKey(nameof(ParentArticleId))] [InverseProperty("ParentArticleHierarchies")] public virtual Article ParentArticle { get; set; } [ForeignKey(nameof(ChildArticleId))] [InverseProperty("ChildArticleHierarchies")] public virtual Article ChildArticle { get; set; } }
Комментарии:
1. Мне нужно было добавить
modelBuilder.Entitylt;ArticleHierarchygt;() .HasKey(e =gt; new { e.ArticleChildId, e.ArticleParentId });
, потому что я получил ошибку при запуске миграции. Теперь миграция выполняется, но когда я запускаю «обновление базы данных», я получаю следующую ошибку: Введение ограничения ВНЕШНЕГО КЛЮЧА «FK_ArticleHierarchy_Article_ArticleParentId» в таблице «ArticleHierarchy» может привести к циклам или нескольким каскадным путям. Укажите ПРИ УДАЛЕНИИ БЕЗ ДЕЙСТВИЯ или ПРИ ОБНОВЛЕНИИ БЕЗ ДЕЙСТВИЯ или измените другие ограничения ВНЕШНЕГО КЛЮЧА. Не удалось создать ограничение или индекс. См. Предыдущие ошибки2. @AnNormalie Удалить конструктор моделей. Сущностьlt;ArticleHierarchygt;() .hasKey(e =lt;ArticleHierarchygt;gt; новый { e.ArticleChildId, e.ArticleParentId }) и сделайте идентификатор в качестве ключа, см. Мой ответ.
3. это помогло устранить ошибку миграции без необходимости кода FluentAPI. Но я все равно получаю ошибку, когда запускаю обновление базы данных. Я исправил это с помощью
modelBuilder.Entitylt;Articlegt;() .HasMany(e =gt; e.ParentArticleHierarchies) .WithOne(e =gt; e.ParentArticle) .OnDelete(DeleteBehavior.Restrict); modelBuilder.Entitylt;Articlegt;() .HasMany(e =gt; e.ChildArticleHierarchies) .WithOne(e =gt; e.ChildArticle) .OnDelete(DeleteBehavior.Restrict);