LINQ to SQL-检查对象是否已选择子,孙等

时间:2013-04-02 11:25:19

标签: c# linq linq-to-sql

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

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

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

只需查找具有您ID的给定ParentFK的任何条目。

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

答案 1 :(得分:1)

从您当前的架构中我无法想到比以下更好的解决方案:

  • 发出查询以检索根目录中所有子项的列表。
  • 发出查询以检索上一步中子项的所有子项的列表。
  • 这样,递归地创建一个根的所有后代的列表。
  • 接下来在DB中查询列表中包含任何关键字的所有媒体对象。

但是上述算法需要多次调用DB。您可以在单个查询中对其进行一些优化。我建议你不仅为每个关键字保留其父FK,还保留其根FK。这样,您可以发出单个查询以获取具有根FK所需关键字的所有对象。