Извлечение древовидной структуры из базы данных с использованием LINQ - PullRequest
7 голосов
/ 06 января 2010

У меня есть древовидная структура организационной диаграммы, хранящаяся в базе данных. Это что-то вроде

ID (int);
Name (String);
ParentID (int)

В C # он представлен классом, подобным

class Employee
{
int ID, 
string Name, 
IList < Employee> Subs
} 

Мне интересно, как лучше всего получить эти значения из базы данных для заполнения объектов C # с помощью LINQ (я использую Entity Framework)

Должно быть что-то лучше, чем звонить, чтобы получить верхний уровень, затем повторять звонки, чтобы получить подпрограммы и т. Д.

Как лучше это сделать?

Ответы [ 5 ]

3 голосов
/ 06 января 2010
  1. Вы можете создать сохраненный процесс со встроенной рекурсией. Посмотрите на http://msdn.microsoft.com/en-us/library/ms190766.aspx для получения дополнительной информации об общих табличных выражениях в SQL Server
  2. Возможно, вы захотите найти другой (лучший?) Способ моделирования ваших данных. http://www.sqlteam.com/article/more-trees-hierarchies-in-sql перечисляет популярный способ моделирования иерархических данных в базе данных. Изменение моделирования может позволить вам создавать запросы, которые могут быть выражены без рекурсии.
2 голосов
/ 17 января 2010

Если вы используете SQL Server 2008, вы можете использовать функцию new HIERARCHYID .

Организации боролись в прошлом с изображением дерева, как структуры в базах данных, много объединяет много сложной логики входит в место, будь то организация иерархия или определение спецификации Материалы) где один готовый продукт зависит от другого полуфабриката материалы / комплектующие изделия и эти комплекты предметы зависят от другого полу готовые изделия или сырье.

SQL Server 2008 имеет решение для проблема, где мы храним весь иерархия в типе данных Hierarchyid` в. HierarchyID является переменной тип данных системы длины. hierarchyid` в используется для определения местоположения в иерархия элемента, как Скотт генеральный директор и Марк, а также Рави сообщает Скотту, Бену и Лоре отчитаться перед Марком, Виджаем, Джеймсом и Фрэнком сообщить Рави.

Так что используйте новые доступные функции и просто возвращайте нужные данные без использования LINQ. Недостатком является то, что вам нужно использовать UDF или хранимые процедуры для всего, кроме простого корневого запроса:

SELECT @Manager = CAST('/1/' AS hierarchyid)         
SELECT @FirstChild = @Manager.GetDescendant(NULL,NULL)  
1 голос
/ 06 января 2010

Я бы добавил к сущности поле для включения родительского идентификатора, а затем вытянул бы всю таблицу в память, оставив подпункты списка пустыми. Затем я перебираю объекты и заполняю список, используя linq для объектов. Только один запрос к БД, поэтому должен быть разумным.

0 голосов
/ 06 января 2010

Ну ... даже с LINQ вам понадобятся два запроса, потому что любой отдельный запрос будет дублировать основного сотрудника и, следовательно, приведет к созданию нескольких сотрудников (которые на самом деле одинаковы) ... Однако вы можете скрыть это немного с linq, когда вы создаете объект, тогда вы выполняете второй запрос, что-то вроде этого:

var v = from u in TblUsers
        select new {
            SupervisorName = u.DisplayName,
            Subs = (from sub in TblUsers where sub.SupervisorID.Value==u.UserID select sub.DisplayName).ToList()
        };
0 голосов
/ 06 января 2010

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

Проверьте это для получения дополнительной информации об этом: http://msdn.microsoft.com/en-us/library/bb896272.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...