#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 и будет ли итерация по узлам более эффективной. Таким образом, вам не придется каждый раз загружать все дерево в память, а вместо этого позволить клиентам обрабатывать это.