具有self-parentId的实体框架核心嵌套对象



我有一个树表结构,这些数据来自前端。在这个树表结构中,有IssueActivity和IssueActivityDetail来获取此问题的详细信息。现在我的问题是,可以将多个IssueActivityDetail字段添加到此IssueActivity字段中。如何在c#ef核心端执行此操作?我试着用ParentId的逻辑来做这件事。我的实体结构如下。我没有在FluentApi中添加parentId,因为我没有完全理解它。

我的IssueActivity表。


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 List<IssueActivitiyDetail> IssueActivitiyDetails { get; set; }
}

我的IssueActivityDetail表。


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

WebApi也是我尝试接收和处理数据的地方,但我玩了很多游戏,无法正确处理。

var vIssueActivity = issueInfo.IssueActivitiyInfos
.Select(a => new IssueActivitiy
{
Type = a.Type,
SubActivityNo = a.SubActivityNo,
SubActivityTitle = a.SubActivityTitle,
IssueActivitiyDetails = a.IssueActivitiyDetailInfos
.Select(x => new IssueActivitiyDetail
{

LineNo = x.LineNo,
Definition = x.Definition,
RoleId = vUser.RoleId,
Medium = x.Medium,
Explanation = x.Explanation,
IssueActivityDetail = new List<IssueActivitiyDetail> { }
}).ToList()
});

您不需要在IssueActivityDetail中保留ParentId属性。

public partial class IssueActivitiy
{
...
public virtual List<IssueActivitiyDetail> IssueActivitiyDetails { get; set; }
}
public partial class IssueActivitiyDetail
{
...
public virtual IssueActivitiy IssueActivity { get; set; }
}

您的配置看起来没有错。

也许您可以在从数据库上下文获取实体时使用Include

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

您可以通过从数据库中检索所有条目来实现这一点。然后选择根节点,然后让EF Core映射完成其余操作。

public class TreeNode 
{
public bool IsRoot { get; set; }
public int? ParentNodeId {get; set;}
public virtual List<TreeNode> ChildNodes {get; set;}
}
public class TreeNodeRepository 
{
public async Task<TreeNode> GetTreeStructure()
{
var allNodes = await _context.TreeNodes.ToListAsync();
return allNodes.FirstOrDefault(t => t.IsRoot);
}
}

您可以争辩说ParentId == null也意味着它是一个父节点。这只会使给出的例子更加直观。

您应该考虑性能,有多少节点将成为一个问题,它是否通过web api公开,并且在节点上迭代会更高效。因此,您不必每次都将整个Tree加载到内存中,而是让客户端来处理它。

相关内容

  • 没有找到相关文章

最新更新