Итак, я понимаю, что опаздываю на вечеринку здесь, однако я решил добавить свои выводы. Это действительно должен быть комментарий к сообщению Алекса Джеймса, но, поскольку у меня нет репутации, мне придется пойти сюда.
Итак, мой ответ: кажется, что он не работает совсем так, как вы хотели бы. Алекс Джеймс предлагает два интересных решения, однако, если вы попробуете их и проверите SQL, это ужасно.
Пример, над которым я работал:
var theRelease = from release in context.Releases
where release.Name == "Hello World"
select release;
var allProductionVersions = from prodVer in context.ProductionVersions
where prodVer.Status == 1
select prodVer;
var combined = (from release in theRelease
join p in allProductionVersions on release.Id equals p.ReleaseID
select release).Include(release => release.ProductionVersions);
var allProductionsForChosenRelease = combined.ToList();
Это следует за более простым из двух примеров. Без включения он производит совершенно респектабельный sql:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name]
FROM [dbo].[Releases] AS [Extent1]
INNER JOIN [dbo].[ProductionVersions] AS [Extent2] ON [Extent1].[Id] = [Extent2].[ReleaseID]
WHERE ('Hello World' = [Extent1].[Name]) AND (1 = [Extent2].[Status])
Но с OMG:
SELECT
[Project1].[Id1] AS [Id],
[Project1].[Id] AS [Id1],
[Project1].[Name] AS [Name],
[Project1].[C1] AS [C1],
[Project1].[Id2] AS [Id2],
[Project1].[Status] AS [Status],
[Project1].[ReleaseID] AS [ReleaseID]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent2].[Id] AS [Id1],
[Extent3].[Id] AS [Id2],
[Extent3].[Status] AS [Status],
[Extent3].[ReleaseID] AS [ReleaseID],
CASE WHEN ([Extent3].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
FROM [dbo].[Releases] AS [Extent1]
INNER JOIN [dbo].[ProductionVersions] AS [Extent2] ON [Extent1].[Id] = [Extent2].[ReleaseID]
LEFT OUTER JOIN [dbo].[ProductionVersions] AS [Extent3] ON [Extent1].[Id] = [Extent3].[ReleaseID]
WHERE ('Hello World' = [Extent1].[Name]) AND (1 = [Extent2].[Status])
) AS [Project1]
ORDER BY [Project1].[Id1] ASC, [Project1].[Id] ASC, [Project1].[C1] ASC
Всего мусора. Ключевым моментом, который следует здесь отметить, является тот факт, что он возвращает внешнюю объединенную версию таблицы, которая не была ограничена статусом = 1.
В результате возвращаются НЕПРАВИЛЬНЫЕ данные:
Id Id1 Name C1 Id2 Status ReleaseID
2 1 Hello World 1 1 2 1
2 1 Hello World 1 2 1 1
Обратите внимание, что там возвращается статус 2, несмотря на наше ограничение. Это просто не работает.
Если я где-то ошибся, я был бы рад узнать, так как это издевательство над Линком. Мне нравится эта идея, но в данный момент казнь не подходит для использования.
Из любопытства я попробовал dbml LinqToSQL, а не edmx LinqToEntities, который привел беспорядок выше:
SELECT [t0].[Id], [t0].[Name], [t2].[Id] AS [Id2], [t2].[Status], [t2].[ReleaseID], (
SELECT COUNT(*)
FROM [dbo].[ProductionVersions] AS [t3]
WHERE [t3].[ReleaseID] = [t0].[Id]
) AS [value]
FROM [dbo].[Releases] AS [t0]
INNER JOIN [dbo].[ProductionVersions] AS [t1] ON [t0].[Id] = [t1].[ReleaseID]
LEFT OUTER JOIN [dbo].[ProductionVersions] AS [t2] ON [t2].[ReleaseID] = [t0].[Id]
WHERE ([t0].[Name] = @p0) AND ([t1].[Status] = @p1)
ORDER BY [t0].[Id], [t1].[Id], [t2].[Id]
Чуть более компактно - странное количество, но в целом тот же FAIL.
Кто-нибудь когда-либо использовал этот материал в реальном бизнес-приложении? Я действительно начинаю задумываться ...
Пожалуйста, скажите мне, что я упустил что-то очевидное, потому что я действительно хочу любить Линка!