Выражение LINQ для CROSS APPLY на два уровня глубже

Довольно новичок в LINQ и пытаюсь понять, как написать конкретный запрос. У меня есть база данных, в которой каждая ЦЕПЬ состоит из одного или нескольких ЗАКАЗОВ, а каждый ЗАКАЗ состоит из одной или нескольких ЧАСТИЧНЫХ. База данных выглядит так:

CREATE TABLE Chain
(
ID         int            NOT NULL  PRIMARY KEY CLUSTERED IDENTITY(1,1),
Ticker     nvarchar(6)    NOT NULL,
Company    nvarchar(128)  NOT NULL
)
GO

CREATE TABLE [Order]
(
ID      int             NOT NULL  PRIMARY KEY CLUSTERED   IDENTITY(1,1),
Chart   varbinary(max)  NULL,
-- Relationships
Chain   int             NOT NULL
)
GO

ALTER TABLE dbo.[Order] ADD CONSTRAINT FK_Order_Chain 
    FOREIGN KEY (Chain) REFERENCES dbo.Chain ON DELETE CASCADE
GO

CREATE TABLE Partial
(
ID           int     NOT NULL  PRIMARY KEY CLUSTERED IDENTITY(1,1),
Date         date    NOT NULL,
Quantity     int     NOT NULL,
Price        money   NOT NULL,
Commission   money   NOT NULL,
-- Relationships
[Order]       int     NOT NULL
)
GO

ALTER TABLE dbo.Partial ADD CONSTRAINT FK_Partial_Order
    FOREIGN KEY ([Order]) REFERENCES dbo.[Order] ON DELETE CASCADE

Я хочу получить цепочки, упорядоченные по самой ранней дате среди всех частей всех заказов для каждой конкретной цепочки. В T-SQL я бы написал запрос так:

SELECT p.DATE, c.*
FROM   CHAIN c
CROSS  APPLY
(
    SELECT DATE = MIN(p.Date)
    FROM   PARTIAL p
    JOIN   [ORDER] o
      ON   p.[ORDER] = o.ID
    WHERE  o.CHAIN = c.ID
) AS p
ORDER BY p.DATE ASC 

У меня есть контекст Entity Framework, который содержит DbSet‹Chain›, DbSet‹Order› и DbSet‹Partial›. Как мне закончить это утверждение, чтобы получить желаемый результат?:

IEnumerable<Chain> chains = db.Chains
                              .Include(c => c.Orders.Select(o => o.Partials))
                              .[WHAT NOW?]

Благодарю вас!


person ekramer17    schedule 31.12.2015    source источник
comment
Это может помочь: linq cross применить   -  person Alicia    schedule 31.12.2015
comment
См. следующую веб-страницу: code.msdn.microsoft.com/101-LINQ-Samples- 3fb9811b   -  person jdweng    schedule 31.12.2015


Ответы (1)


.[ЧТО ТЕПЕРЬ?]

.OrderBy(c => c.Orders.SelectMany(o => o.Partials).Min(p => p.Date))

Здесь c.Orders соединяет Chain с Order, а o.SelectMany(o => o.Partials) соединяет Order с Partial. Получив доступ к Partial записям, вы можете использовать любую агрегатную функцию, например Min(p => p.Date) в вашем случае.

person Ivan Stoev    schedule 31.12.2015
comment
А, хорошо, я понял. SelectMany — одно из самых запутанных выражений на первый взгляд, но ваше объяснение делает его очень ясным. Спасибо, Иван! - person ekramer17; 31.12.2015