为何Entity Framework Core生成多查询而非单条UNION查询?
在EF Core 2.0.1中合并查询生成单条UNION SQL
嘿,你写的代码其实已经踩对节奏了!EF Core 2.0.1里的Union方法默认就会把两个查询合并成一条带UNION的SQL语句发送给SQL Server,而不是先分别执行两个查询再在内存里做合并操作。
咱们来看你的示例代码:
using (var dbc = new ItemsDbContext("some-connection-string")) { var q1 = dbc.Items.Where(a => a.ItemType == "A"); var q2 = dbc.Items.Where(a => a.ItemType == "B"); var myList = q1.Union(q2).ToList(); }
执行这段代码后,EF Core会自动生成类似这样的单条SQL发送给SQL Server:
SELECT [a].[Id], [a].[ItemType], [a].[OtherColumn] -- 这里是你Items表的实际列 FROM [Items] AS [a] WHERE [a].[ItemType] = N'A' UNION SELECT [a].[Id], [a].[ItemType], [a].[OtherColumn] FROM [Items] AS [a] WHERE [a].[ItemType] = N'B'
如果你想确认生成的SQL是不是符合预期,可以给你的ItemsDbContext加上日志配置,把EF Core生成的SQL输出到控制台或者日志文件:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("some-connection-string") .LogTo(Console.WriteLine, Microsoft.Extensions.Logging.LogLevel.Information); }
运行代码后,你就能在控制台看到实际发送给数据库的SQL语句,直接验证是不是单条UNION查询。
另外还有几个小细节要注意:
- 两个查询的返回结构必须完全匹配:列的数量、顺序、数据类型都得一致,不然EF Core要么报错,要么会退化成在内存里合并结果(这就不是单条SQL了)。
- 如果你的业务场景不需要去重,推荐用
UnionAll替代Union,它会生成UNION ALL的SQL,性能比UNION更好(因为跳过了去重步骤),用法和Union一样:var myList = q1.UnionAll(q2).ToList();
总的来说,你的代码本身是正确的,只要保证两个查询的结构一致,就能得到你想要的单条UNION SQL啦!
内容的提问来源于stack exchange,提问作者Dima
相关产品推荐
相关产品推荐

