$("#slide").animate({width:'toggle'},350);
Ссылка: https://api.jquery.com/animate/
.
Если вы отбросите все четыре таблицы (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.
Я создал ваши таблицы в базе данных 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
Если вы делаете это с помощью прямого LINQ to SQL, без какой-либо рекурсии это невозможно сделать, независимо от того, делаете ли вы это сами или скрываете это за методом расширения. Рекурсивный SQL - это очень плохо (много циклов, много одиночных запросов).
Здесь есть два варианта. Один из них - вытащить всю таблицу (ы) с иерархией в память и использовать на ней LINQ to Objects. Оставьте таблицы «деталей» в SQL. Если у вас меньше нескольких тысяч сущностей, это, вероятно, самый эффективный способ. Вы можете сохранить одну копию таблицы (таблиц) в кеше и обновлять их при необходимости. Когда вам нужно получить более подробные данные из БД для одной записи, вы можете повторно подключить этот объект из кэшированной иерархии к новому DataContext и получить его.
Другой вариант - использовать более сложную модель отношений в вашей базе данных. Сохранение родительского объекта только по своей природе требует рекурсии, но вы можете использовать модель списка смежности , чтобы создать один запрос, который может охватывать множество уровней наследования. Это будет означать, что ваши запросы LINQ to SQL станут менее интуитивно понятными (запросы к Entity.Right
и Entity.Left
не так красивы, как Parent
или ] Children
...), но вы можете сделать в одном запросе то, что может занять сотни или тысячи при буквальном рекурсивном подходе.