【问题标题】:How can I code a recursive search for linked database entities?如何对链接数据库实体进行递归搜索?
【发布时间】:2019-08-18 00:33:59
【问题描述】:

我正在构建一个动态 CDN 以供内部使用。我们有大量在业务中使用的 Web 应用程序,并且正在建立一个 CDN,以便所有 JS 库(Bootstrap、Jquery 等)继续存在。为了帮助创建项目,我们创建了一个数据库,其中有一个用于库的表,以及一个用于库需求的表(即 Bootstrap 需要 Jquery)。使用需求数据库中的数据,webAPI 将返回一个包含脚本标签和 css 链接标签的列表,以用于 _Layout.cshtml 页面。

有问题的数据库表是 tblLibrary & tblLibraryRequirements

tblLibraryRequirements 表由以下列组成: - ID - [图书馆ID] - [需要身份证]

我有一个深入 3 层的工作模型,通过嵌套 foreach 循环将需求的 tblLibrary 对象添加到所有相关库的主列表中。通过 .Distinct() 删除重复项

        public ActionResult<List<string>> GetSciptTags_config(int ConfigID)
        {
            List<TblLibrary> LibraryRecsToScript = new List<TblLibrary>();

            // Get a list of libraries in the project config
            List<TblProjectConfigLibraries> configLibraries = db.TblProjectConfigLibraries.Where(s => s.ConfigurationId == ConfigID).ToList();

            foreach (TblProjectConfigLibraries configLibRec in configLibraries)
            {
                // get the tblLibrary record for the supplied ID
                TblLibrary libRec = db.TblLibrary.FirstOrDefault(s => s.Id == configLibRec.LibraryId);

                // find any requirement libraries
                List<TblLibraryRequirements> requirementRecs = db.TblLibraryRequirements.Where(s => s.LibraryId == configLibRec.LibraryId).ToList();

                foreach (TblLibraryRequirements item in requirementRecs)
                {
                    TblLibrary reqLibRec = db.TblLibrary.FirstOrDefault(s => s.Id == item.RequiresId);
                    // check that the requirement doesnt have requirements
                    List<TblLibraryRequirements> reqs = db.TblLibraryRequirements.Where(s => s.LibraryId == reqLibRec.Id).ToList();
                    foreach (TblLibraryRequirements req in reqs)
                    {
                        TblLibrary reqLibRec2 = db.TblLibrary.FirstOrDefault(s => s.Id == req.RequiresId);
                        LibraryRecsToScript.Add(reqLibRec2);
                    }
                    LibraryRecsToScript.Add(reqLibRec);
                }
                LibraryRecsToScript.Add(libRec);

            }

            // Remove Duplicates
            LibraryRecsToScript = LibraryRecsToScript.Distinct().ToList();
            // Get Scripts
            List<string> scripts = getScriptTags(LibraryRecsToScript);
            return scripts;
        }

以上内容适用于前 3 个级别,但采用我们拥有的 css 库,它需要 Bootstrap-DatePicker,然后我希望它可以追溯到 JQuery。

-即library1依赖libraray2,libraray2依赖library3,library3依赖library4等

我确信必须有更好的方法来做到这一点,但我没能直接在脑海中将它编码出来。

非常感谢任何帮助。对拼写、语法和格式问题深表歉意。

【问题讨论】:

  • 我不确定这是一个好方法;您还需要解决版本控制问题,因为一个包正在从特定版本开始获得新的依赖关系;为什么不只托管静态文件?
  • 文件本身托管于此​​,tblLibrary 表具有名称和版本作为其架构的一部分。这里的想法是,使用 UI,团队成员可以选择他们想要的库并为他们生成脚本标签,包括依赖项

标签: c# entity-framework recursion search


【解决方案1】:

我找到了解决办法。它可能没有它应该的那么优雅,但它似乎在我的测试中有效。

我已更新控制器 Action 以调用传入初始 ID 的函数

 public ActionResult<List<string>> GetSciptTags_config(int ConfigID)
        {
            List<TblLibrary> LibraryRecsToScript = new List<TblLibrary>();

            // Get a list of libraries in the project config
            List<TblProjectConfigLibraries> configLibraries = db.TblProjectConfigLibraries.Where(s => s.ConfigurationId == ConfigID).ToList();

            foreach (TblProjectConfigLibraries configLibRec in configLibraries)
            {
                LibraryRecsToScript.AddRange(GetLibraryList(configLibRec.LibraryId));
            }

            // Get Scripts
            List<string> scripts = getScriptTags(LibraryRecsToScript);
            return scripts;
        }

这会将 tblLibrary 对象添加到名为 librariesSeen 的外部列表中,并且对于每个调用,检查它是否已添加到 librarySeen 以停止无限循环。

 private List<TblLibrary> GetLibraryList(int libraryID)
        {
            List<TblLibrary> retVal = new List<TblLibrary>();
            // master list of records found is a class wide variable so that this routine can be called from within itself
            TblLibrary libRec = db.TblLibrary.FirstOrDefault(s=> s.Id == libraryID);

            librariesSeen.Add(libRec);
            if (retVal.Contains(libRec) == false)
            {
                List<TblLibraryRequirements> requirementsFound = db.TblLibraryRequirements.Where(s => s.LibraryId == libraryID).ToList();
                foreach (TblLibraryRequirements req in requirementsFound)
                {
                    TblLibrary reqLibRecord = db.TblLibrary.FirstOrDefault(s => s.Id == req.RequiresId);
                    if (librariesSeen.Contains(reqLibRecord) == false)
                    {
                        retVal.AddRange(GetLibraryList(reqLibRecord.Id));
                    }
                }
                retVal.Add(libRec);

                // Remove Duplicates
                retVal = retVal.Distinct().ToList();
            }
            return retVal;
        }

希望这对其他人有帮助 =)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    相关资源
    最近更新 更多