Проще говоря, есть ли способ принудить LinqToSql
к созданию целых конкат, не вставляя утверждения UNION ALL
?
Пример:
a.Concat(b).Concat(c)
приводит к чему-то семантически подобному:
SELECT * FROM (
SELECT * FROM A
UNION ALL
SELECT * FROM B
)
UNION ALL
SELECT * FROM C
Было бы гораздо читабельнее/предпочтительнее, если бы я мог убедить его:
SELECT * FROM A
UNION ALL
SELECT * FROM B
UNION ALL
SELECT * FROM C
Я понимаю, почему он это делает (и я даже не уверен, что эти две вещи точно такие же семантически), но есть ли способ сделать это возможным? Это сделало бы кучу наших сгенерированных запросов значительно легче читать и отлаживать.
SQL, созданный из LINQ, не предназначен для чтения, поэтому я не думаю, что есть способ сделать это. Было бы хорошо, я согласен. Это одна из причин, по которой я заинтригован концепцией микроорганизмов ORM, таких как Dapper, поэтому я могу просто написать свой собственный SQL.
У меня возникли проблемы с объединением большого автогенерированного набора iqueryables, так как поведение вложенности созданного SQL-запроса просто слишком глубоко для обработки sql. Я решил это, объединив элементы в стиле бинар-дерева, например:
public static IQueryable<T> BinaryConcatenation<T>(this IEnumerable<IQueryable<T>> queries)
{
var count = queries.Count();
var firsthalf = queries.Take(count / 2).ToArray();
var secondhalf = queries.Skip(count / 2).ToArray();
if (firsthalf.Length == 0 || secondhalf.Length == 0) return queries.Aggregate((src, next) => src.Concat(next));
var first = BinaryConcatenation(firsthalf);
var second = BinaryConcatenation(secondhalf);
return first.Concat(second);
}
Таким образом, сгенерированная глубина вложенности SQL становится значительно ниже (log (n)?).