我的Postgres DB中有一个具有复合键{ A, B, C }的实体。在我的应用程序中,我有一个包含组合键值的Tuples列表,并且我试图查询表,以获取其组合键是该列表的一部分的所有数据库记录。通过编写一个纯SQL查询,我可以这样做:
SELECT *
FROM my_table
WHERE (A, B, C) IN ( ('A', 1, 1), ('B', 1, 2), ('C', 2, 1) );然而,当我尝试通过EF核心DbContext来做这件事时,我得到了一个异常,LINQ查询不能被翻译。这是我试图执行的查询:
IEnumerable<Tuple<string, int, int>> keys = // ...
var entities = dbContext.MyTable
.Where(e => keys.Contains(new Tuple<string, int, int>(e.A, e.B, e.C)))
.ToList();使用EF Core5.0.1和.NET 5的正确方法是什么?
发布于 2021-02-10 23:37:46
一种解决方法是将多个Union连接起来:
IQueryable<MyTable> query = null;
foreach (var t in x)
{
var interim = dbContext.MyTable.Where(mc => mc.A == t.Item1 && mc.B == t.Item2 && mc.C == t.Item3);
query = query?.Union(interim) ?? interim;
}
var entities = query.ToList();您还可以为Where子句构建expression tree:
Expression<Func<MyTable, Tuple<string, int, int>, bool>> sel = (mc, t) => mc.A == t.Item1 && mc.B == t.Item2 && mc.C == t.Item3;
Expression<Func<MyTable, bool>> baseExpr = mc => false;
var resBody = baseExpr.Body;
var body = new ReplacingExpressionVisitor(new[] {sel.Parameters[0]}, new[] {baseExpr.Parameters[0]}).Visit(sel.Body);
foreach (var tuple in x)
{
var expression = new ReplacingExpressionVisitor(new[] {sel.Parameters[1]}, new[] {Expression.Constant(tuple)}).Visit(body);
resBody = Expression.OrElse(resBody, expression);
}
var res = Expression.Lambda<Func<MyTable, bool>>(resBody, baseExpr.Parameters);
var entities = dbContext.MyTable
.Where(res)
.ToList();https://stackoverflow.com/questions/66138224
复制相似问题