关于Dynamics 365多选选项集在使用Contains-value时失效问题的分析与解决
几个月前我们遇到了一个问题,我把我们整个解决问题的过程记录下来,希望让自己也让大家可以少走一些弯路:
我们在user表中有一个position字段,它是多选选项集字段,这个字段也用在了其他实体上,用户反馈搜不到某些user,我们就去查了一下,发现理论上这个user记录应该被用户所查到,我们又检查了这个用户的权限发现权限也没问题,后来我们查了fetchxml,发现是fetchxml确实没有查到。
这就有意思了,我们又用管理员权限去查,并且比对了每一个条件,发现条件就是符合的,但就是搜不到这个user,随后我们又去user表里检查了这个用户,发现这个user的position字段也是有值的。
在这之后我们又检查了MultiSelectAttributeOptionValuesBase这张表,因为如果我们直接使用sql语句插入一条带有多选选项集的数据,而没有将数据也相应的插入到MultiSelectAttributeOptionValuesBase这张表是会有查不到的情况,但检查了这张表,发现里面也有对应的记录...真是怪事年年有,今年特别多。
后来实在没办法,我们又使用SQL Profiler去抓取这个查询在后台的sql语句,并且也抓取了能够正常查询到数据的user记录进行了对比,我把这条sql语句也粘贴了出来,大家可以看下。
select
top 251 ( select count(1) from SystemUser where ParentSystemUserId = "systemuser0".SystemUserId ) as "HierarchyDataChildCountcd9e4c001441b09237d51a34853d"
, "systemuser0".ParentSystemUserId as "parentsystemuserid"
, "systemuser0".FullName as "fullname"
, "systemuser0".Address1_Telephone1 as "address1_telephone1"
, "systemuser0".BusinessUnitId as "businessunitid"
, "systemuser0".abc_phone as "abc_phone"
, "systemuser0".abc_issanforemployee as "abc_issanforemployee"
, "systemuser0".abc_employeestatus as "abc_employeestatus"
, "systemuser0".abc_employeeno as "abc_employeeno"
, "systemuser0".abc_email as "abc_email"
, "systemuser0".Title as "title"
, "systemuser0".abc_position as "abc_position"
, "systemuser0".SystemUserId as "systemuserid"
, convert(bigint, "systemuser0".VersionNumber) as "versionnumber"
, "systemuser0".EntityImage_URL as "entityimage_url"
, "systemuser0".ParentSystemUserIdName as "parentsystemuseridname"
, "systemuser0".ParentSystemUserIdYomiName as "parentsystemuseridyominame"
, "systemuser0".BusinessUnitIdName as "businessunitidname"
, "systemuser0".systemuserid as "systemuserid"
, "msj0".ObjectId as "ObjectId"
, "msj0".ObjectIdTypeCode as "ObjectIdTypeCode"
, "msj0".ObjectColumnNumber as "ObjectColumnNumber"
, "msj0".SelectedOptionValues as "SelectedOptionValues"
from
SystemUser as "systemuser0"
left outer join MultiSelectAttributeOptionValuesBase as "msj0" on ("msj0".ObjectId = "systemuser0".SystemUserId and "msj0".ObjectIdTypeCode = 8 and "msj0".ObjectColumnNumber = 10015)
where
("systemuser0".IsDisabled = 0 and "systemuser0".abc_issanforemployee = 1 and "systemuser0".systemuserid = N'XXXXXXXX-f057-f011-a12a-XXXXXXXXXX')
--and msj0.SelectedOptionValues like N'%920400007%'
and contains("msj0".SelectedOptionValues, N'920400007')
order by
"systemuser0".FullName asc
, "systemuser0".SystemUserId asc;
我将里面的条件一个一个的去掉最后发现是contains("msj0".SelectedOptionValues, N'920400007')这条语句的问题
在这期间我们已经给微软提了ticket,我也把我的调查结果反馈给了他们,他们又把结果反馈给了微软产品组,微软产品组让我们抓取系统的trace log,我尝试使用powershell命令去开启log指令,但是却并不好使,后来使用了修改注册表的方式才开启的log,并把抓取的log文件传给了微软。开启tracelog的过程如果大家有想了解的可以看我的上一篇博文Dynamics 365(on-premise)开启追踪日志-CSDN博客
之后微软给了回复,需要我检查这几个表,我把检查步骤也贴出来了,大家可以看下

我运行了这三个命令分别在我们的UAT和生产环境,我们uat环境是没问题的,比较了之后发现两个环境确实是有区别的


最后通过这个区别推断出来,我们这个MultiSelectAttributeOptionValuesBase表的全文索引是有问题的,微软给我们的建议是再次触发这张表的全文索引的完整填充,使用下面的命令
ALTER FULLTEXT INDEX ON MultiSelectAttributeOptionValuesBase START FULL POPULATION
如果事情真的这么顺利就好了,我尝试运行了这个命令结果报错了...
警告: 启动对表或索引视图 'MultiSelectAttributeOptionValuesBase' 的全文检索填充的请求已被忽略,因为此表或索引视图当前已有活动的填充。
完成时间: 2025-11-01T09:42:51.8391732+08:00
最后,我们借助ai,ai给我们的答案是先用如下命令检查返回是否0行,如果返回 0 行,说明 SQL Server 内部已把任务标记为“丢失”,但元数据没更新,这就是典型的“僵尸填充”。
SELECT *
FROM sys.dm_fts_index_population
WHERE table_id = OBJECT_ID('MultiSelectAttributeOptionValuesBase');
我运行上面的命令之后返回的是0行,AI给我们的答案是运行如下命令
-- 1. 停止填充
ALTER FULLTEXT INDEX ON MultiSelectAttributeOptionValuesBase STOP POPULATION;-- 2. 关闭再启用全文索引(重置状态)
ALTER FULLTEXT INDEX ON MultiSelectAttributeOptionValuesBase DISABLE;
ALTER FULLTEXT INDEX ON MultiSelectAttributeOptionValuesBase ENABLE;-- 3. 重新启动完整填充(Full Population)
ALTER FULLTEXT INDEX ON MultiSelectAttributeOptionValuesBase START FULL POPULATION;
我们运行了这个命令发现没有像上面一样报错,并且显示的更新时间也是最近的时间了,我们也在D365的页面,通过使用contains-value条件去筛选之前查不到的那条数据现在也能顺利查到了。
至此这个问题算是彻底解决了,但至于为什么会发生索引失效的问题,我还在查,一旦查到原因我会在更新一篇博文来说明一下。
