【问题标题】:Combine multiple queries for checking existence of database records in different tables组合多个查询以检查不同表中数据库记录的存在
【发布时间】:2023-02-07 05:18:51
【问题描述】:

我有一个函数需要验证单独数据库表中某些记录的存在。目前我使用单独的查询来执行此操作,以便我可以返回相关的错误消息。下面是一个人为的例子:

var a = await context.EntityA.FirstOrDefaultAsync(e => e.id == entityAId);
var b = await context.EntityB.FirstOrDefaultAsync(e => e.id == entityBId);
var c = await context.EntityC.FirstOrDefaultAsync(e => e.id == entityCId);

if (a == default) return "Entity A ID is invalid";
if (b == default) return "Entity B ID is invalid";
if (c == default) return "Entity C ID is invalid";

对于三个单独的调用,这感觉效率很低。有没有一种方法可以组合这些调用并且仍然知道哪些(如果有的话)检查失败以便可以形成适当的响应?

【问题讨论】:

  • 答案是否定的,除非您使用提供“未来查询”的第三方库。但是有单独的调用真的没什么大不了的(有连接池)。如果您实际上不需要实体对象,您最好联系我们Any()。
  • +1 使用Any()。使用 FirstOrDefault() 会产生加载整个实体的成本,只是为了确定是否有一行。 Any() 将组成一个查询,该查询仅返回一行是否存在。对于诸如通过 PK/Indexed 值进行的存在检查之类的事情,我也不会为 async 调用的开销而烦恼,只需使用同步调用即可。 async 对于在等待重要操作时保持服务器响应很有用,但是如果按顺序运行查询会更快,它会增加开销成本。

标签: .net entity-framework


【解决方案1】:

Entity Framework (Core) 支持 Contains 关键字,它将转换为 in 的 SQL 等价物。 (这取决于您的数据库提供商,但大多数关系数据库都支持这种方法)。

实体框架查询

    var ids = new[] { 1, 2, 3 };
    var sql = db.Animals
        .Where(a => ids.Contains(a.Id))
        .Select(a => new { a.Id })
        .ToQueryString();
    
    Console.WriteLine(sql);

结果 SQL

SELECT "a"."Id"
FROM "Animals" AS "a"
WHERE "a"."Id" IN (1, 2, 3)

如何使用结果

标识符只有在数据库中存在时才会返回。因此,查看结果集以确定内存中缺少哪些元素。

这减少了对数据库的网络调用3个到1个.

干杯!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 2023-02-22
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多