LINQ to SQL для самодостаточных таблиц?

У меня есть саморегулирующаяся таблица категорий. У каждой категории есть CategoryID, ParentCategoryID, CategoryName и т. д. И каждая категория может иметь любое количество подкатегорий, и каждая из этих подкатегорий может иметь любое количество подкатегорий и так далее. Таким образом, дерево может иметь глубину X уровней.

Затем Товары связываются с конечными (подкатегориями). Есть ли способ получить все продукты для любой данной категории (которые будут всеми продуктами, связанными со всеми ее конечными потомками) с помощью LINQ to SQL?

Это похоже на рекурсивную проблему. Лучше вместо этого использовать хранимую процедуру?

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
5
0
4 861
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вот ужасная поспешная реализация с использованием LINQ. Не используйте это :-)

public IQueryable GetCategories(Category parent)
{
    var cats = (parent.Categories);
    foreach (Category c in cats )
    {
        cats  = cats .Concat(GetCategories(c));
    }
    return a;
}

Эффективный подход заключается в создании триггера вставки / изменения / удаления, который поддерживает совершенно другую таблицу, содержащую пары узел-предок для всех предков всех узлов. Таким образом, поиск выполняется за O (N).

Чтобы использовать его для получения всех продуктов, принадлежащих узлу и всем его потомкам, вы можете просто выбрать все узлы категорий, у которых ваш целевой узел является предком. После этого вы просто выбираете любые продукты, относящиеся к любой из этих категорий.

Ответ принят как подходящий

Я не думаю, что у linq-to-sql есть хороший ответ на эту проблему. Поскольку вы используете sql server 2005, вы можете использовать CTE для выполнения иерархических запросов. Либо хранимая процедура, либо встроенный запрос (с использованием DataContext.ExecuteQuery) сделают свое дело.

Я справляюсь с этим, используя некоторые методы расширения (фильтры). Я написал пример кода из проекта, в котором реализовал это. Обратите особое внимание на строки, в которых я заполняю объект ParentPartner и список SubPartners.

public IQueryable<Partner> GetPartners()
        {
            return from p in db.Partners
                   select new Partner
                   {
                       PartnerId = p.PartnerId,
                       CompanyName = p.CompanyName,
                       Address1 = p.Address1,
                       Address2 = p.Address2,
                       Website = p.Website,
                       City = p.City,
                       State = p.State,
                       County = p.County,
                       Country = p.Country,
                       Zip = p.Zip,
                       ParentPartner = GetPartners().WithPartnerId(p.ParentPartnerId).ToList().SingleOrDefault(),
                       SubPartners = GetPartners().WithParentPartnerId(p.PartnerId).ToList()
                   };
        }


public static IQueryable<Partner> WithPartnerId(this IQueryable<Partner> qry, int? partnerId)
        {
            return from t in qry
                   where t.PartnerId == partnerId
                   select t;
        }

public static IQueryable<Partner> WithParentPartnerId(this IQueryable<Partner> qry, int? parentPartnerId)
        {
            return from p in qry
                   where p.ParentPartner.PartnerId == parentPartnerId
                   select p;
        }

Я думаю, что это отличная идея, но я получаю сообщение об ошибке при попытке ее реализовать. В нем говорится, что методы расширения WithPartnerId не поддерживают преобразование в SQL. Есть идеи?

JC Grubbs 09.03.2009 23:29

Другие вопросы по теме