2015-02-18 2 views
0

Предположим, у вас есть база данных продуктов, эти продукты привязаны к региону. В каждом регионе есть родительские -> детские отношения. Например, допустим, вы можете купить банан в любой точке США, яблоко в любом месте в Миннесоте и оранжевый в любом месте в Миннеаполисе.Иерархический запрос Linq to SQL

Если бы я искал, чтобы получить список продуктов, доступных для продажи в Миннеаполисе (Банан, Яблоко, Оранжевый), я мог бы сделать запрос Linq следующим образом.

public static List<Product> GetProducts(int regionId) 
{ 
    using (var db = new DataContext()) 
    { 
     return (from p in db.Products 
       where GetRegions(regionId).Contains(p.Region) 
       select p).ToList(); 
     } 
    } 
} 

То, что я не могу придумать что GetRegions будет выглядеть, я просто сделать Перечислите необязательный параметр, а затем сделать добавления в коллекцию рекурсивно? Или есть что-то более умное (менее ручное), встроенное в синтаксис Linq, о котором я не знаю?

GetRegions

// Pseudo code, untested. I feel like it should be easier. 
private static List<Region> GetRegions(int regionId, List<Region> regions = null) 
{ 
    if (regions == null) 
     regions = new List<Region>(); 

    using (var db = new DataContext()) 
    { 
     var data = (from r in db.Regions 
        where r.Id == regionId 
        select r).SingleOrDefault(); 

     if (data != null) 
     { 
      regions.Add(data); 
      regions = GetRegions((int)data.ParentId, regions); 
     } 
    } 

    return regions; 
} 
+0

могли бы вы, пожалуйста, добавить код 'GetRegions' m енишь? –

+0

@FelipeOriani Я добавил возможную реализацию GetRegions, я не запускал ее через компилятор, я не уверен, что это работает, это всего лишь представление направления, в котором я возглавлялся, и я задаюсь вопросом, нет ли чего-то более естественно, что я пропустил. –

+0

Скорее, это LINQ to Entities, и невозможно записать рекурсивные запросы в LINQ to Entities. Но можно написать рекурсивный запрос, используя синтаксис 'WITH ... AS (SELECT ...)', а затем выполнить его с использованием контекста данных, вызвав метод запроса обобщенного выполнения, который автоматически заполняет объект такими же свойствами, как и запись в записи (скажем, 'IEnumerable '. –

ответ

0

Вы можете сохранить результат GetRegions() в регионах, а затем сделать что-то вроде этого

List<Product> productsToDisplay = new List<Product>(); 

    regions.ForEach(t => 
     { 
      productsToDisplay.AddRange(products.Where(u => u.RegionId == t.RegionId)); 
     } 
); 

ИЛИ

productsToDisplay = (from product in products 
           join region in regions 
           on product.RegionId equals region.RegionId 
           select product).ToList<Product>(); 
+0

Я думаю, что я не вижу значения? GetProducts выглядит довольно чистым и работает, что я могу сделать лучше, это GetRegions? –

Смежные вопросы