1

我一直在到处寻找答案,但找不到任何东西。我有两个表,媒体和关键字,它们具有多对多的关系。现在,Keywords 表非常简单 - 它有一个 ID、Name 和 ParentFK 列,这些列与 ID 列相关(它是一个树结构)。用户可以将任何单个关键字分配给媒体文件,这意味着他可以选择叶子而不选择根或分支。

现在我必须能够确定根关键字是否有分配给媒体对象的子、孙等,但我必须从根开始。

任何帮助将不胜感激。

4

2 回答 2

1

只需查找任何将给定的 ParentFK 设置为您的 ID 的条目。

public static bool HasChild(int id) {
    return
        db.Keywords.Any(item => item.Parent == id);
}

public static bool HasGrandChilds(int id) {
    return
        db.Keywords.Where(item => item.Parent == id).Any(item => HasChild(item.ID);
}

更通用的方法:

public static bool HasGrandChilds(int id, int depth) {
    var lst = new List<Keywords>();
    for (var i = 0; i < depth - 1; i++) {
        if (i == 0)
        {
            //Initial search at first loop run
            lst = db.Keywords.Where(item => item.ParentId == id);
        }
        else
        {
            //Search all entries, where the parent is in our given possible parents
            lst = db.Keywords.Where(item => lst.Any(k => k.Id == item.Parent));
        }
        if (!lst.Any())
        {
            //If no more children where found, the searched depth doesn't exist
            return false;
        }
    }
    return true;
}
于 2013-04-02T11:33:15.010 回答
1

从您当前的架构中,我想不出比以下更好的解决方案:

  • 发出查询以检索根的所有子项的列表。
  • 发出查询以检索上一步中子项的所有子项的列表。
  • 依此类推,递归地创建根的所有后代的列表。
  • 接下来查询数据库中具有列表中任何关键字的所有媒体对象。

但上述算法将需要多次调用数据库。您可以在一个查询中完成它,您可以稍微改进您的架构。我建议您不仅为每个关键字保留其父 FK,还保留其根 FK。这样,您可以发出单个查询来获取所有具有其根 FK 是所需关键字的对象。

于 2013-04-02T11:39:47.517 回答