如何修复DeleteManyAsync返回0条用Filter删除的记录?

时间:2019-04-11 14:53:25

标签: c# mongodb filter ienumerable mongodb-.net-driver

我有一个delete方法,该方法接受IEnumerable类型的Id(其类型为string),并具有一个使用Filter.In接受这些ID的过滤器。但是,当传入一组ID时,删除记录的计数为0。我的过滤器是否引起了问题?

我创建了一个测试方法来测试我的删除方法,并传入ID尝试删除它们。


测试解决方案

MongodDB删除方法的测试方法

    [Theory]
    [InlineData(1)]
    [InlineData(100)]
    public async void TEST_DELETE(int quantity)
    {
        using (var server = StartServer())
        {
            // Arrange
            var collection = SetupCollection(server.Database, quantity);
            var dataUtility = new MongoDataUtility(server.Database, 
    MongoDbSettings);
            var service = new MongoDatabaseService(dataUtility, Logger);

            var items = 
    collection.FindSync(FilterDefinition<BsonDocument>.Empty)
    .ToIdCollection();
            _output.WriteLine(JsonConvert.SerializeObject(items, 
    Formatting.Indented));

            // Act
            var result = await 
    dataUtility.DeleteIdentifiedDataAsync(items, CollectionName);
            _output.WriteLine(JsonConvert.SerializeObject(result, 
    Formatting.Indented));

            // Assert
            Assert.True(result.DeletedCount.Equals(items.Count));
        }
    }

设置集合

    public IMongoCollection<BsonDocument> SetupCollection(IMongoDatabase db, 
    int quantity)
    {
        var collection = db.GetCollection<BsonDocument>(CollectionName);

        AddCreateDateIndex(collection);
        SeedData(collection, quantity);

        return collection;
    }

种子数据

    public void SeedData(IMongoCollection<BsonDocument> collection, int? 
    quantity = null)
    {
        if (quantity != null && quantity > 0)
        {
            collection.InsertMany(GenerateTestData((int)quantity));
        }
    }

项目

MongoDB删除方法

 public async Task<DeleteResult> 
 DeleteIdentifiedDataAsync(IEnumerable<ObjectId> ids, string Resource, 
 CancellationToken cancellationToken = default)
    {
        var collection = _db.GetCollection<BsonDocument>(Resource);
        var filter = Builders<BsonDocument>.Filter.In("_id", ids);

        if (ids != null && ids.Any() )
        {
            return await collection.DeleteManyAsync(filter, 
 cancellationToken);
        }

        return null;
    }

扩展名

    public static ICollection<ObjectId> ToIdCollection(this 
    IAsyncCursor<BsonDocument> @this)
    {
        return @this.Find(Builders<BsonDocument>.Filter.Empty)
            .ToEnumerable()
            .Select(s => s["_id"].AsObjectId)
            .ToList();
    }

1 个答案:

答案 0 :(得分:1)

您的ToIdCollection方法将获取所有ids,但也会在您运行ObjectId时将它们从String转换为.Select(dict => dict["_id"].ToString())。运行DeleteManyAsync时,MongoDB会同时比较值和类型,这就是为什么不匹配的原因-您正尝试将字符串列表与数据库中存储的ObjectId进行比较。

要解决此问题,您可以将ToIdCollection替换为以下实现:

return @this.Find(Builders<BsonDocument>.Filter.Empty)
                        .ToEnumerable()
                        .Select(s => s["_id"].AsObjectId)
                        .ToList()