LinqToSql - 由CONCAT(UNION)生成的SQL

时间:2014-05-16 03:40:38

标签: c# tsql linq-to-sql

简单地说,有没有办法强制LinqToSql生成链接的concats而不嵌套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

我理解它为什么会这样做(我甚至不确定这两个东西在语义上是完全相同的)但有没有办法让这种情况发生?它会使我们生成的一堆查询更容易阅读和调试。

2 个答案:

答案 0 :(得分:0)

从LINQ生成的SQL不是设计为可读的,所以我认为没有办法做到这一点。我同意,这会很好。这是我对像Dapper这样的微ORM概念感兴趣的一个原因,所以我可以编写自己的SQL。

答案 1 :(得分:0)

我遇到了连接大量自动生成的iqueryables的问题,因为生成的sql查询的嵌套行为对于sql来说太简单了。我通过以类似binare-tree的方式连接项目来解决它:

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)?)。