EF Core 8中Union LINQ查询无法处理自定义数据的问题
问题原因
EF Core的LINQ查询最终要转换为数据库可执行的SQL语句。当你调用Union([newAttempt])时,传入的是内存中的IEnumerable集合,EF Core无法将内存中的Attempt对象直接翻译为SQL里的常量SELECT语句(也就是你示例SQL中SELECT 'My_data', 56, 'Also_My_Data'这部分)。
EF Core要求Union操作的两端都必须是可翻译为数据库查询的IQueryable类型,而内存集合不属于这个范畴,因此抛出无法翻译的异常。
解决方案
方案1:构造可翻译的常量查询(推荐,数据库端执行Union)
通过构造一个能被EF Core翻译为SQL常量行的IQueryable,让Union操作完全在数据库端执行:
// 构造一个返回单条自定义Attempt的IQueryable var customAttemptQuery = db.Attempt .Select(_ => new Attempt(7, "Herb", 56)) .Take(1); // 确保只生成一行数据 // 执行Union查询 var attemptsUnionOne = await db.Attempt .Union(customAttemptQuery) .ToListAsync();
或者直接使用原生SQL构造自定义数据的查询(更直观):
var customAttempts = db.Attempt.FromSqlRaw("SELECT 7 AS Id, 'Herb' AS UserId, 56 AS score"); var attemptsUnionOne = await db.Attempt.Union(customAttempts).ToListAsync();
方案2:客户端执行Union(适合数据量小的场景)
如果数据库中数据量不大,可以先把表中数据拉取到客户端内存,再和自定义对象做Union:
// 先加载数据库数据到内存 var dbAttempts = await db.Attempt.ToListAsync(); // 在客户端执行Union var attemptsUnionOne = dbAttempts.Union([newAttempt]).ToList();
注意:这种方式会把所有数据库中的Attempt数据加载到内存,数据量大时会影响性能。
内容的提问来源于stack exchange,提问作者Tomer Trashman
相关产品推荐
相关产品推荐

