SOQL查询EmailMessage记录不全:无with sharing类与控制台结果差异原因
我来帮你梳理下这个问题的几个常见原因,都是Salesforce里容易踩的坑:
上下文用户权限与控制台用户不一致
虽然你的类没加with sharing,但类运行时的上下文用户(比如触发类的用户、API调用的登录用户)和你在开发者控制台登录的用户权限可能不一样。比如控制台用的是系统管理员(有View All Data权限),而类运行的用户没有这个权限,同时EmailMessage的共享模型是受控于父对象(比如关联的Case),那即使类是without sharing,查询时还是会因为用户没有父对象的访问权限,导致对应的EmailMessage被过滤掉。你可以检查下类运行的用户有没有View All Data,或者是否能访问所有关联的父记录。未包含软删除/归档记录
开发者控制台的查询编辑器默认如果勾选了「Include Deleted and Archived Records」选项,会返回软删除或归档的EmailMessage;而普通的SOQL查询(不加ALL ROWS关键字)只会返回活跃的记录。如果你的类里的查询没加ALL ROWS,那自然会比控制台的结果少。你可以在类的查询里加上ALL ROWS试试:SELECT Id, Status FROM EmailMessage ALL ROWS同时去控制台确认下是不是勾选了包含删除记录的选项。
隐式的过滤逻辑干扰
有时候可能你以为类里的查询是无条件的,但实际上可能有其他逻辑悄悄修改了结果。比如是不是类里用了Database.query(),字符串拼接时不小心加了过滤条件?或者有没有EmailMessage的触发器、自动化流程在查询前做了数据过滤?你可以把类里的查询语句单独拎出来,在控制台切换到类运行的用户身份执行,看看结果是不是和类里一致。对象级权限限制(可能性较低)
即使类是without sharing,如果上下文用户没有EmailMessage对象的「Read」权限,查询也会返回异常结果。不过这种情况比较少见,因为如果没有读权限,控制台用该用户查询也会返回空,但你说控制台能返回所有,所以这个可以作为最后排查的点。
内容的提问来源于stack exchange,提问作者Mangesh Honale

