首页 > 解决方案 > 使用 ef 核心中的 OR 条件基于所有可选参数的动态查询

问题描述

我不确定我是不是找错了树,但我想创建一个函数来根据所有可选参数检查帐户是否存在,这样它就可以用来根据你想要检查的任何内容来提取数据.

基本上,查询应该是:其中 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

我确定我错过了一些东西,有没有更好的方法?

标签: linqentity-framework-coreef-core-3.1

解决方案


您使用的适用于可选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));

推荐阅读