C# 在MySQL和实体框架中删除注释及其所有子项的SQL查询

C# 在MySQL和实体框架中删除注释及其所有子项的SQL查询,c#,mysql,sql,entity-framework,linq,C#,Mysql,Sql,Entity Framework,Linq,我有一个评论表 身份证 截面图 父项注释id 根id 内容 它支持多层次的评论 如果注释位于最上面的位置,则其根注释id为空注释id,其父注释id为空注释id 如果注释位于另一个注释下面:父注释id等于注释的注释id,该注释id仅位于注释下面的一个级别。所有子注释的root_id将是位于其下方的最上面注释的id 例如: [id=1] [parent_comment_id=null] [root_id=null] [id=2] [parent_comment_id=1] [root_id=

我有一个评论表

  • 身份证
  • 截面图
  • 父项注释id
  • 根id
  • 内容
它支持多层次的评论

如果注释位于最上面的位置,则其
根注释id
空注释id
,其
父注释id
空注释id

如果注释位于另一个注释下面:父注释id等于注释的注释id,该注释id仅位于注释下面的一个级别。所有子注释的root_id将是位于其下方的最上面注释的id

例如:

[id=1] [parent_comment_id=null] [root_id=null]
  [id=2] [parent_comment_id=1] [root_id=1]
  [id=3] [parent_comment_id=1] [root_id=1]
    [id=4] [parent_comment_id=3] [root_id=1]
      [id=5] [parent_comment_id=4] [root_id=1]
    [id=12] [parent_comment_id=3] [root_id=1]
  [id=6] [parent_comment_id=1] [root_id=1]

[id=2] [parent_comment_id=null] [root_id=null]
我无法控制数据库模式。所以我不能改变。表中也没有为这些列中的任何列设置外键约束

我遇到的问题是创建一个函数,可能是一个递归函数,它获取注释Id并删除该注释及其所有子项,所有级别的子项。这可以是树中任意位置的注释

下面是我正在尝试的一些东西:

 protected void DeleteChildComments(comment c)
 {
      // get all comments with c.id as its parent_id
      List<comment> oneLevelDownSubComments = new List<comment>();

      using (phEntities db = new phEntities())
       {
           oneLevelDownSubComments = db.comments.Where(x => x.parent_comment_id == c.id).ToList<comment>();    

       }

        if (oneLevelDownSubComments.Count == 0)
        {
            // no children, just delete the comment
            using (phEntities db = new (phEntities())
            {
                db.comments.Remove(c);
                db.SaveChanges();
            }
        }
        else
        {
            // has children
            foreach(var item in oneLevelDownSubComments)
            {
                DeleteChildComments(item);
            }
        }

    }
受保护的void DeleteChildComments(注释c)
{
//获取以c.id作为其父\u id的所有注释
List oneLevelDownSubComments=新列表();
使用(phenties db=new phenties())
{
oneLevelDownSubComments=db.comments.Where(x=>x.parent_comment_id==c.id).ToList();
}
if(oneLevelDownSubComments.Count==0)
{
//没有子项,只需删除注释即可
使用(phenties db=new(phenties())
{
db.注释。删除(c);
db.SaveChanges();
}
}
其他的
{
//有孩子
foreach(oneLevelDownSubComments中的var项)
{
删除评论(项目);
}
}
}

我正在使用ASP.NET 4.5 C#和实体框架开发MySQL 5数据库。

好的,我终于成功了,代码如下:

  protected void DeleteChildComments(comment c, phEntities db) {
   if (c != null) {
    // get all comments with c.id as its parent_id
    List <comment> oneLevelDownSubComments = new List <comment> ();

    oneLevelDownSubComments =
        db.comments.Where(x => x.parent_comment_id == c.id).ToList <comment> ();

    if (oneLevelDownSubComments.Count == 0) {
     // no children, just delete the comment

     db.comments.Remove(c);
     db.SaveChanges();
    } else {
     // has children, delete them
     foreach(var item in oneLevelDownSubComments) {
      DeleteChildComments(item, db);
     }

     // delete itself if has no children
     DeleteChildComments(c, db);
    }
   }
  }
受保护的void DeleteChildComments(注释c、phEntities db){
如果(c!=null){
//获取以c.id作为其父\u id的所有注释
List oneLevelDownSubComments=新列表();
oneLevelDownSubComments=
其中(x=>x.parent\u comment\u id==c.id).ToList();
if(oneLevelDownSubComments.Count==0){
//没有子项,只需删除注释即可
db.注释。删除(c);
db.SaveChanges();
}否则{
//如果有子项,请删除它们
foreach(oneLevelDownSubComments中的var项){
删除注释(项目,db);
}
//如果没有子项,则删除自身
删除注释(c、db);
}
}
}

类似的东西怎么样

protected void DeleteComment(comment c)
{
    int id = c.id

    //Three lists to hold the self-referencing objects
    List<comment> rootCommentsToBeDeleted = new List<comment>();
    List<comment> parentCommentsToBeDeleted = new List<comment>();
    List<comment> commentsToBeDeleted = new List<comment>();

    using (phEntities db = new phEntities())
    {

        //Get all comments to lists
        rootCommentsToBeDeleted = db.comments.Where(x => x.root_id == id).ToList<comment>();    
        parentCommentsToBeDeleted = db.comments.Where(x => x.parent_comment_id == id).ToList<comment>();    
        commentsToBeDeleted = db.comments.Where(x => x.id == id).ToList<comment>();    

        //Combine lists
        commentsToBeDeleted.AddRange(rootCommentsToBeDeleted);
        commentsToBeDeleted.AddRange(parentCommentsToBeDeleted);

        //Delete records
        db.comments.RemoveRange(commentsToBeDeleted);
        db.SaveChanges();

    }

}
受保护的无效删除注释(注释c)
{
int id=c.id
//保存自引用对象的三个列表
List rootCommentsToBeDeleted=新列表();
List parentCommentsToBeDeleted=新列表();
List commentsToBeDeleted=新列表();
使用(phenties db=new phenties())
{
//获取列表中的所有注释
rootCommentsToBeDeleted=db.comments.Where(x=>x.root_id==id.ToList();
parentCommentsToBeDeleted=db.comments.Where(x=>x.parent\u comment\u id==id).ToList();
commentsToBeDeleted=db.comments.Where(x=>x.id==id.ToList();
//合并列表
AddRange(rootCommentsToBeDeleted);
AddRange(parentCommentsToBeDeleted);
//删除记录
db.comments.RemoveRange(commentsToBeDeleted);
db.SaveChanges();
}
}

您应该能够为此使用级联外键约束。@GordonLinoff这些列中的任何一列都没有约束。您可以创建数据库对象吗?是否向表中添加触发器?@TroyWitthoeft不,我不能创建触发器。项目使用实体框架,因此我可以访问表示列的对象这样我就可以像db.comments.where(x=>x.id==1)一样查询数据库。可能有一个递归函数,但它可能更简单?看起来两个串行delete语句就可以完成。删除where
root\u id=1
(子项),然后再删除其中的'id=1'(父项)。我必须是递归的,因为有无限级,我需要从树的底部遍历到第一个注释。我添加了我的答案,递归遍历树,直到它包含要删除的注释,并将其删除。谢谢你的回答。哦,抱歉。我不知道你在处理无限级的l伊芙·特里。对我来说,它看起来只有三个。这是一个例子,但我在这个问题上展示了几个深度。无论如何,谢谢你试图帮助我的朋友。明白了。那么,是的,我想你找到了你问题的答案。你的答案被高估了。:)