Linq解析器问题

本文关键字:问题 Linq | 更新日期: 2023-09-27 18:28:18

好吧,我不确定我是错了还是linq解析错误了,但如果我不使用额外的括号,下面的linq查询会返回我不想要的内容。

int? userLevel;
Guid? supervisorId;
List<int> levelsIds = new List<int>();
string hierarchyPath;
// init the vars above
// ...
var qry = from f in items
          where userLevel.HasValue
                   ? (f.IsMinLevelIdNull() || (levelsIds.Contains(f.MinLevelId)))
                   : true
                && supervisorId.HasValue
                   ? (f.IsSupervisorIdNull() || (!f.ChildrenVisibility && (f.SupervisorId == supervisorId.Value))
                        || (f.ChildrenVisibility && (hierarchyPath.IndexOf(f.SupervisorId.ToString()) >= 0)))
                   : true
          select f;

这里的想法是在变量"userLevel"answers"supervisorId"的存在"激活"的两个条件块之间用AND运行查询。

例如,如果userLevel和supervisorId都为空,则查询变为:

var qry = from f in items
          where true && true
          select f;

好吧,只有当我在额外的括号中加上两个触发器时,这个查询才能正常工作:

var qry = from f in items
          where (userLevel.HasValue
                       ? (f.IsMinLevelIdNull() || (levelsIds.Contains(f.MinLevelId)))
                       : true)
                 && (supervisorId.HasValue
                       ? (f.IsSupervisorIdNull() || (!f.ChildrenVisibility && (f.SupervisorId == supervisorId.Value))
                       || (f.ChildrenVisibility && (hierarchyPath.IndexOf(f.SupervisorId.ToString()) >= 0)))
                   : true)
          select f;

问题是:为什么需要额外的括号?我的观点是linq解析器中存在问题。

Linq解析器问题

7.2.1运算符优先级和关联性&&? : 之前进行评估

由于优先级的计算顺序错误,因此需要额外的括号。例如,由于true&amp;supervisorId.HasValue…

var qry = from f in items  
      where 
        1st: userLevel.HasValue
            ? 
        2nd: (f.IsMinLevelIdNull() || (levelsIds.Contains(f.MinLevelId))) 
            : 
        3rd: true && supervisorId.HasValue  
               ? (f.IsSupervisorIdNull() || (!f.ChildrenVisibility && (f.SupervisorId == supervisorId.Value))  
                    || (f.ChildrenVisibility && (hierarchyPath.IndexOf(f.SupervisorId.ToString()) >= 0)))  **)**
               : true  
      select f;