一个带有语句体的 Lambda 表达式无法转换为表达式树。

huangapple go评论66阅读模式
英文:

A lambda expression with statement body cannot be converted to an expression tree

问题

return _employeeRepository.Get().SingleOrDefault(employee =>
{
    var mailPrefix = employee.LoginName.Split('@')[0];

    if (!string.IsNullOrEmpty(employee.LoginName)
        && employee.IsActive.Value 
        && !string.IsNullOrEmpty(employee.AdGuid)
        && string.Equals(mailPrefix, guestLoginName))
    {
        return true;
    }
    return false;
});

错误:具有语句体的 Lambda 表达式无法转换为表达式树

英文:
            return _employeeRepository.Get().SingleOrDefault(employee =>
            {
                var mailPrefix = employee.LoginName.Split('@')[0];

                if (!string.IsNullOrEmpty(employee.LoginName)
                    && employee.IsActive.Value 
                    && !string.IsNullOrEmpty(employee.AdGuid)
                    && string.Equals(mailPrefix, guestLoginName))
                {
                    return true;
                }
                return false;
            });

Error: A lambda expression with statement body cannot be converted to an expression tree

答案1

得分: 1

Sure, here's the translated code:

将员工的谓词逻辑分离为独立的布尔方法应该可以解决问题 - 代码的简单修改:

private bool IsEmployeeLoginNameValid(Employee employee)
{
   var mailPrefix = employee.LoginName.Split('@')[0];

                if (!string.IsNullOrEmpty(employee.LoginName)
                    && employee.IsActive.Value 
                    && !string.IsNullOrEmpty(employee.AdGuid)
                    && string.Equals(mailPrefix, guestLoginName))
                {
                    return true;
                }
                return false;
}

然后只需这样使用它:

return _employeeRepository.Get().SingleOrDefault(IsEmployeeLoginNameValid);

或者

return _employeeRepository.Get().SingleOrDefault(employee => IsEmployeeLoginNameValid(employee));

编辑:如果你的 .Get() 返回 IQueryable,你将不得不先实例化集合以使我的建议起作用 - 否则可能会抛出错误 - 我猜你正在使用 EF 和标准查询通过仓储将 LINQ 转换为本地 SQL 查询。因此,任何本地方法/表达式都不会起作用,因为查询提供程序将无法将其转换为 SQL 查询。
英文:

Separating your predicate logic for the employee to standalone bool method should work - a simple modification of the code:

private bool IsEmployeeLoginNameValid(Employee employee)
{
   var mailPrefix = employee.LoginName.Split('@')[0];

                if (!string.IsNullOrEmpty(employee.LoginName)
                    && employee.IsActive.Value 
                    && !string.IsNullOrEmpty(employee.AdGuid)
                    && string.Equals(mailPrefix, guestLoginName))
                {
                    return true;
                }
                return false;
}

Then just use it like this:

return _employeeRepository.Get().SingleOrDefault(IsEmployeeLoginNameValid);

Or

return _employeeRepository.Get().SingleOrDefault(employee => IsEmployeeLoginNameValid(employee));

EDIT: If you .Get() return IQueryable, you will have to materialize the collection first in order to make my suggestion work - otherwise it could throw an error -> I guess you are using EF and standard queries via repository translates the LINQ to native SQL query. So any local method/expression will not work because the query provider will not be able to transform it to sql query.

huangapple
  • 本文由 发表于 2023年5月11日 17:57:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76226378.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定