Как я могу запросить эти иерархические данные с помощью LINQ?

$("#slide").animate({width:'toggle'},350);

Ссылка: https://api.jquery.com/animate/

.

5
задан KingNestor 25 June 2009 в 00:58
поделиться

3 ответа

Если вы отбросите все четыре таблицы (Agency, BusinessUnit, Client, Map) в конструкторе linq to sql и нарисуете связи из карты с тремя другими, на карте появятся некоторые полезные свойства. .

  //construct a query to fetch the row/column shaped results.
var query = 
  from m in db.map
  //where m.... ?
  let a = m.Agency
  let b = m.BusinessUnit
  let c = m.Client
  // where something about a or b or c ?
  select new {
    AgencyID = a.AgencyID,
    AgencyName = a.Name,
    BusinessUnitID = b.BusinessUnitID,
    ClientID = c.ClientID,
    NumberOfAccounts = c.NumberOfAccounts,
    Score = c.Score
  };
  //hit the database
var rawRecords = query.ToList();

  //shape the results further into a hierarchy.    
List<Agency> results = rawRecords
  .GroupBy(x => x.AgencyID)
  .Select(g => new Agency()
  {
    Name = g.First().AgencyName,
    BusinessUnits = g
    .GroupBy(y => y.BusinessUnitID)
    .Select(g2 => new BusinessUnit()
    {
      Clients = g2
      .Select(z => new Client()
      {
        NumberOfAccounts = z.NumberOfAccounts,
        Score = z.Score
      })
    })
  })
  .ToList();

Если предоставлены подходящие фильтры (см. Закомментированные предложения where ), то в память будут загружены только необходимые части таблиц. Здесь работает стандартное соединение SQL.

4
ответ дан 14 December 2019 в 13:44
поделиться

Я создал ваши таблицы в базе данных SQL Server и попытался воссоздать ваш сценарий в LinqPad. В итоге я получил следующие операторы LINQ, которые в основном приводят к той же структуре ваших классов POCO:

var map =   from bac in BAC_Maps
            join a in Agencies on bac.Agency_ID equals a.Agency_ID
            join b in BusinessUnits on bac.Business_Unit_ID equals b.Business_Unit_ID
            join c in Clients on bac.Client_ID equals c.Client_ID
            select new 
            { 
                AgencyID        =   a.Agency_ID,
                BusinessUnitID  =   b.Business_Unit_ID,
                Client          =   c
            };

var results =   from m in map.ToList()
                group m by m.AgencyID into g
                select new 
                {
                    BusinessUnits = from m2 in g
                                    group m2 by m2.BusinessUnitID into g2
                                    select new
                                    {
                                        Clients = from m3 in g2
                                                select m3.Client
                                    }
                };

results.Dump();

Обратите внимание, что я вызвал map.ToList () во втором запросе. Фактически это привело к единственному эффективному запросу. Моя первоначальная попытка не включала .ToList () и привела к девяти отдельным запросам для получения тех же результатов. Запрос, созданный версией .ToList (), выглядит следующим образом:

SELECT [t1].[Agency_ID] AS [AgencyID], [t2].[Business_Unit_ID] AS [BusinessUnitID], [t3].[Client_ID], [t3].[NumberOfAccounts], [t3].[AmountOfPlacement], [t3].[AvgBalance], [t3].[NeuPlacementScore]
FROM [BAC_Map] AS [t0]
INNER JOIN [Agencies] AS [t1] ON [t0].[Agency_ID] = [t1].[Agency_ID]
INNER JOIN [BusinessUnits] AS [t2] ON [t0].[Business_Unit_ID] = [t2].[Business_Unit_ID]
INNER JOIN [Clients] AS [t3] ON [t0].[Client_ID] = [t3].[Client_ID]

Вот скриншот результатов:

alt text http://img411.imageshack.us/img411/5003/agencybusinessunitclien.png

2
ответ дан 14 December 2019 в 13:44
поделиться

Если вы делаете это с помощью прямого LINQ to SQL, без какой-либо рекурсии это невозможно сделать, независимо от того, делаете ли вы это сами или скрываете это за методом расширения. Рекурсивный SQL - это очень плохо (много циклов, много одиночных запросов).

Здесь есть два варианта. Один из них - вытащить всю таблицу (ы) с иерархией в память и использовать на ней LINQ to Objects. Оставьте таблицы «деталей» в SQL. Если у вас меньше нескольких тысяч сущностей, это, вероятно, самый эффективный способ. Вы можете сохранить одну копию таблицы (таблиц) в кеше и обновлять их при необходимости. Когда вам нужно получить более подробные данные из БД для одной записи, вы можете повторно подключить этот объект из кэшированной иерархии к новому DataContext и получить его.

Другой вариант - использовать более сложную модель отношений в вашей базе данных. Сохранение родительского объекта только по своей природе требует рекурсии, но вы можете использовать модель списка смежности , чтобы создать один запрос, который может охватывать множество уровней наследования. Это будет означать, что ваши запросы LINQ to SQL станут менее интуитивно понятными (запросы к Entity.Right и Entity.Left не так красивы, как Parent или ] Children ...), но вы можете сделать в одном запросе то, что может занять сотни или тысячи при буквальном рекурсивном подходе.

0
ответ дан 14 December 2019 в 13:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: