在 ef 核心中使用 OR 条件基于所有可选参数的动态查询

Dynamic Query based on all optional parameters using an OR condition in ef core

我不确定我是否找错了树,但我想创建一个函数来根据所有可选参数检查帐户是否存在,以便它可以用于根据您的任何情况提取数据'我想看看。

基本上查询应该是: 其中 loginName = p1 或 loginName = p2 或 loginName = p3 但参数都是可选的,但至少会提供一个。

这是我到目前为止尝试过的:

 public async Task<bool> CheckAccountExistsAsync(string loginName = "", string authenticatorId = "", string eId = "")
    {
      if (string.IsNullOrWhiteSpace(loginName) && string.IsNullOrWhiteSpace(authenticatorId) && string.IsNullOrWhiteSpace(eId))
        throw new InvalidOperationException("You must pass at least one parameter");

      return await _context.Accounts.AnyAsync(a =>
          (string.IsNullOrWhiteSpace(loginName) || a.LoginName == loginName)
          || (string.IsNullOrWhiteSpace(authenticatorId) || a.AuthenticatorId == authenticatorId)
          || (string.IsNullOrWhiteSpace(eId) || a.EmployeeId == eId));
    }

这种方法的问题是,如果我只传递登录名,则查询如下,条件完全省略。:

      SELECT CASE
          WHEN EXISTS (
              SELECT 1
              FROM [Accounts] AS [a]) THEN CAST(1 AS bit)
          ELSE CAST(0 AS bit)
      END

我确定我遗漏了什么,有更好的方法吗?

您使用的适用于可选的 and 表达式,例如

return await _context.Accounts.AnyAsync(a =>
    (string.IsNullOrWhiteSpace(loginName) || a.LoginName == loginName)
    && (string.IsNullOrWhiteSpace(authenticatorId) || a.AuthenticatorId == authenticatorId)
    && (string.IsNullOrWhiteSpace(eId) || a.EmployeeId == eId));

对于可选的 or,您必须使用可选的 and 子条件,并为所有缺少的可选参数添加额外检查,例如

return await _context.Accounts.AnyAsync(a =>
    (string.IsNullOrWhiteSpace(loginName)
    && string.IsNullOrWhiteSpace(authenticatorId)
    && string.IsNullOrWhiteSpace(eId))
    || (!string.IsNullOrWhiteSpace(loginName) && a.LoginName == loginName)
    || (!string.IsNullOrWhiteSpace(authenticatorId) && a.AuthenticatorId == authenticatorId)
    || (!string.IsNullOrWhiteSpace(eId) && a.EmployeeId == eId));