【问题标题】:entity framework core nested object with self parentId具有自身 parentId 的实体框架核心嵌套对象
【发布时间】:2022-01-08 20:11:43
【问题描述】:

我有一个树表结构,这些数据来自前端。 在这个树形表结构中,有 IssueActivity 和 IssueActivityDetail 来了解这个问题的细节。 现在我的问题是,这个 IssueActivity 字段可以添加多个 IssueActivityDetail 字段。如何在 c# ef 核心方面做到这一点? 我试图用 ParentId 的逻辑来做。我的实体结构如下。 FluenApi中没有添加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 Aktivite\r\n2) Alternatif Aktivite\r\n3) İş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_");
}

Web Api也是我尝试接收和处理数据的地方,但是玩了很多,都做不好。

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()
});

【问题讨论】:

    标签: c# entity-framework entity-framework-core ef-fluent-api


    【解决方案1】:

    您无需将ParentId 属性保留在IssueActivityDetail 中。

    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();
    

    【讨论】:

      【解决方案2】:

      您可以通过从数据库中检索所有条目来完成此操作。然后选择 Root 节点,然后让 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 也暗示它是一个父节点。这只是让 imo 给出的示例更加直观。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-13
        • 1970-01-01
        • 2019-12-08
        • 2017-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-04
        相关资源
        最近更新 更多