#c# #entity-framework #recursion #search
#c# #entity-framework #рекурсия #Поиск
Вопрос:
Я создаю динамический CDN для внутреннего использования на работе. У нас есть огромное количество веб-приложений, которые мы использовали в бизнесе, и мы настраиваем CDN, чтобы все библиотеки JS (Bootstrap, Jquery и т.д.) Продолжали работать. Чтобы облегчить создание проекта, мы создали базу данных, в которой у нас есть таблица для библиотек, а также таблица для требований библиотеки (т. Е. для начальной загрузки требуется Jquery). Используя данные в базе данных в соответствии с требованиями, WebAPI вернет список, содержащий теги сценариев и css-теги ссылок для использования на страницах _Layout.cshtml.
Рассматриваемые таблицы базы данных — это tblLibrary amp; tblLibraryRequirements
Таблица tblLibraryRequirements состоит из следующих столбцов: — 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, который зависит от library3, который зависит от library4 и т. Д
Я уверен, что должен быть лучший способ сделать это, но у меня не получается разобраться в своей голове, чтобы закодировать это.
Любая помощь приветствуется. Приношу извинения за проблемы с правописанием, грамматикой и форматом.
Комментарии:
1. я не уверен, что это хороший подход; вам также нужно будет обратиться к управлению версиями, поскольку один пакет получает новую зависимость, начиная с определенной версии; почему бы просто не разместить статические файлы?
2. Сами файлы размещаются на этом, таблица tblLibrary имеет имя и версию как часть своей схемы. Идея здесь в том, что с помощью пользовательского интерфейса член команды может выбирать нужные библиотеки, и для них генерируются теги скрипта, включая зависимости
Ответ №1:
Я нашел решение. Возможно, это не так элегантно, как могло бы быть, но, похоже, работает в моих тестах.
Я обновил действие контроллера, чтобы теперь вызывать функцию, передающую начальный идентификатор
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, и при каждом вызове проверяйте, был ли он уже добавлен в librariesSeen, чтобы остановить бесконечный цикл.
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;
}
Надеюсь, это поможет кому-то еще =)