основной вложенный объект entity framework core с собственным родительским идентификатором

#c# #entity-framework #entity-framework-core #ef-fluent-api

#c# #структура организации #сущность-структура-ядро #ef-fluent-api

Вопрос:

У меня есть древовидная структура, и эти данные поступают ко мне с интерфейса. В этой древовидной структуре есть IssueActivity и IssueActivityDetail для получения подробной информации об этой проблеме. Теперь мой вопрос в том, что в это поле IssueActivity можно добавить более одного поля IssueActivityDetail. Как я могу сделать это на стороне ядра c# ef? Я попытался сделать это с логикой родителя. Мои структуры сущностей следующие. Я не добавил родительский код в FluenApi, потому что не до конца его понял.

Моя таблица активности проблем.

  public partial class IssueActivitiy { public int Id { get; set; } public int IssueId { get; set; } public byte Type { get; set; } public short SubActivityNo { get; set; } public string SubActivityTitle { get; set; } public virtual Issue Issue { get; set; } public virtual Listlt;IssueActivitiyDetailgt; IssueActivitiyDetails { get; set; } }   

Моя таблица активности вопросов.

  public partial class IssueActivitiyDetail { public int Id { get; set; } public int IssueActivityId { get; set; } public short LineNo { get; set; } public string Definition { get; set; } public byte RoleId { get; set; } public byte Medium { get; set; } public string Explanation { get; set; } public int? ParentId { get; set; } public virtual IssueActivitiy IssueActivity { get; set; } }  

Конфигурация FluentAPI.

  public void Configure(EntityTypeBuilderlt;IssueActivitiygt; modelBuilder) { modelBuilder.ToTable("IssueActivitiy"); modelBuilder.HasKey(a =gt; a.Id); modelBuilder.Property(e =gt; e.SubActivityNo).HasComment("Sıra No"); modelBuilder.Property(e =gt; e.SubActivityTitle).HasMaxLength(256).IsUnicode(false); modelBuilder.Property(e =gt; e.Type).HasDefaultValueSql("((1))").HasComment("1) Temel Aktivitern2) Alternatif Aktivitern3) İşlem İptal Aktivite"); modelBuilder.HasOne(d =gt; d.Issue).WithMany(p =gt; p.IssueActivitiys).HasForeignKey(d =gt; d.IssueId).OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_Issue_IssueActivitiy_Id"); } public void Configure(EntityTypeBuilderlt;IssueActivitiyDetailgt; modelBuilder) { modelBuilder.ToTable("IssueActivitiyDetail"); modelBuilder.Property(e =gt; e.Definition).IsRequired().HasMaxLength(2048).IsUnicode(false).HasComment("Açıklama"); modelBuilder.Property(e =gt; e.Explanation).HasMaxLength(2048).IsUnicode(false).HasComment("Açıklama"); modelBuilder.Property(e =gt; e.IssueActivityId).HasComment("Konu Id"); modelBuilder.Property(e =gt; e.LineNo).HasComment("Sıra No"); modelBuilder.Property(e =gt; e.Medium).HasComment("Ortam (Excel, Mail vb.)"); modelBuilder.Property(e =gt; e.RoleId).HasComment("Rol"); modelBuilder.Property(e =gt; e.ParentId); modelBuilder.HasOne(d =gt; d.IssueActivity).WithMany(p =gt; p.IssueActivitiyDetails).HasForeignKey(d =gt; d.IssueActivityId).OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_IssueActivitiy_IssueActivitiyDetail_"); }  

Веб-Api также является местом, где я пытаюсь получать и обрабатывать данные, но я много играл и не мог сделать это правильно.

 var vIssueActivity = issueInfo.IssueActivitiyInfos .Select(a =gt; new IssueActivitiy { Type = a.Type, SubActivityNo = a.SubActivityNo, SubActivityTitle = a.SubActivityTitle, IssueActivitiyDetails = a.IssueActivitiyDetailInfos .Select(x =gt; new IssueActivitiyDetail {   LineNo = x.LineNo, Definition = x.Definition, RoleId = vUser.RoleId, Medium = x.Medium, Explanation = x.Explanation, IssueActivityDetail = new Listlt;IssueActivitiyDetailgt; { } }).ToList() });  

Ответ №1:

Вам не нужно хранить ParentId собственность внутри IssueActivityDetail .

 public partial class IssueActivitiy {  ...  public virtual Listlt;IssueActivitiyDetailgt; IssueActivitiyDetails { get; set; } }  
 public partial class IssueActivitiyDetail {  ...  public virtual IssueActivitiy IssueActivity { get; set; } }  

Ваша конфигурация не выглядит неправильной.

Возможно, вы можете использовать Include его при получении сущности из контекста БД.

 var issueActivity = context.IssueActivities.Include(x =gt; x.IssueActivityDetails).FirstOrDefault();  

Ответ №2:

Вы можете сделать это, извлекая все записи из базы данных. Затем выберите корневой узел, а затем позвольте EF Core mapping сделать все остальное.

 public class TreeNode  {  public bool IsRoot { get; set; }  public int? ParentNodeId {get; set;}  public virtual Listlt;TreeNodegt; ChildNodes {get; set;} }  public class TreeNodeRepository  {   public async Tasklt;TreeNodegt; GetTreeStructure()  {  var allNodes = await _context.TreeNodes.ToListAsync();   return allNodes.FirstOrDefault(t =gt; t.IsRoot);  }  }  

Вы могли бы возразить, что ParentId == null это также означает, что это родительский узел. это просто делает приведенный пример более точным, имо.

Вам следует подумать о производительности, о том, сколько узлов станет проблемой, будет ли она доступна через веб-api и будет ли итерация по узлам более эффективной. Таким образом, вам не придется каждый раз загружать все дерево в память, а вместо этого позволить клиентам обрабатывать это.