我试图实现以下过滤器目标:
UpdateDescription.UpdateFields
中任何一个字段的存在以及操作类型
为了实现目标,我尝试使用
PipelineDefinition.Match
扩展函数的表达式类型参数重载,如下所示:
var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<BsonDocument>>()
.Match(
(ChangeStreamDocument<BsonDocument> doc) =>
doc.UpdateDescription.UpdatedFields.Any(c => fieldNameList.Contains(c.Name))
&&
doc.OperationType == _operationType);
但我最终收到以下错误:
System.NotSupportedException: 'Serializer for MongoDB.Driver.ChangeStreamUpdateDescription must implement IBsonDocumentSerializer to be used with LINQ.'
我尝试向
ChangeStreamDocumentSerializer
提供一个新的 EmptyPipelineDefinition
实例以及匹配过滤器,但也出现了相同的错误。
如何在 LINQ 过滤器中使用
UpdateDescription
?
我最终构建了 FilterDefinition 和 FieldDefinition 来解决所描述的问题:
builder.Ne($"updateDescription.updatedFields.{memberExpression.Member.Name}", BsonNull.Value)
我使用循环构建最终解决方案,如下所示:
var dynamicFilter = builder.Empty;
var fieldFilter = new List<FilterDefinition<ChangeStreamDocument<BsonDocument>>>();
var operationFilter = new List<FilterDefinition<ChangeStreamDocument<BsonDocument>>>();
foreach (var field in _fields)
{
var memberExpression = (MemberExpression)field.Body;
fieldFilter.Add(builder
.Ne($"updateDescription.updatedFields.{memberExpression.Member.Name}", BsonNull.Value));
}
foreach (var operationType in _operationTypes)
{
operationFilter.Add(builder.Eq(c => c.OperationType, operationType));
}
dynamicFilter = builder.And(builder.Or(fieldFilter), builder.Or(operationFilter));
为了编译时安全,我更愿意使用类型化变体而不是过滤器定义字符串,但我遇到了本文中报告的原始问题的另一种表现形式。我相信那些基于字符串的字段定义是区分大小写的。因此,使用此解决方案时请务必小心。