Я пытаюсь вручную объединить деревья выражений для достижения уровня модульности, который, кажется, намекает на меня, используя стандартные операторы linq. Код по существу создает дерево выражений, которое использует одно выражение, чтобы решить, какое из двух других выражений вызвать. Для одного из других выражений требуется дополнительный параметр, который сам получается с использованием другого выражения. Этот параметр используется для получения нескольких значений, но для каждого доступа выражение, которое извлекает параметр, повторяется. Я включил код и вывод, чтобы лучше объяснить:
public void Test() {
var parameters = ProjectionOne.Parameters;
Expression<Func<Foo, bool>> isType = f => f.TypeId == 1;
Expression<Func<Foo, Satellite>> satSelector = f => f.Satellites.Single();
var satelliteSelector = Expression.Invoke(satSelector, parameters[0]);
var test = Expression.Lambda<Func<Foo, Bar>>(
Expression.Condition(
Expression.Invoke(isType, parameters[0]),
Expression.Invoke(ProjectionOne, parameters[0]),
Expression.Invoke(ProjectionTwo, parameters[0], satelliteSelector)), parameters);
}
public Expression<Func<Foo, Bar>> ProjectionOne {
get {
return foo => new Bar() {
Id = foo.Id
};
}
}
public Expression<Func<Foo, Satellite, Bar>> ProjectionTwo {
get {
return (foo, sat) => new Bar() {
Id = foo.Id,
Start = sat.Start,
End = sat.End
};
}
}
Когда я запускаю этот запрос к базе данных, SQL выдается следующим образом:
SELECT [t0].[value], [t0].[value2] AS [Start], [t0].[value3] AS [End], [t0].[Id] AS [Id]
FROM (
SELECT
(CASE
WHEN [t0].[TypeId] = @p0 THEN 1
WHEN NOT ([t0].[TypeId] = @p0) THEN 0
ELSE NULL
END) AS [value], (
SELECT [t2].[Start]
FROM [dbo].[Satellite] AS [t2]
WHERE [t2].[Id] = [t0].[Id]
) AS [value2], (
SELECT [t2].[End]
FROM [dbo].[Satellite] AS [t2]
WHERE [t2].[Id] = [t0].[Id]
) AS [value3], [t0].[Id]
FROM [dbo].[Foo] ) AS [t0]
Проблема в том, что дубликат суб-выбора. Один получает значение «Старт», а другой - значение «Конец». Было бы намного лучше, если бы они оба были получены из одного суб-выбора. Как я могу изменить конструкцию дерева выражений для обеспечения этого? Кроме того, я понимаю, что существуют более простые способы выполнить этот запрос, однако он является частью большой структуры, не показанной здесь, которая может быть достигнута только путем возможности вручную собрать деревья выражений из большого набора многократно используемых выражений.