У меня есть метод удаления, который принимает IEnumerable из идентификаторов, которые имеют тип строки, и есть фильтр, принимающий эти идентификаторы с помощью Filter.In. Однако при передаче набора идентификаторов я получаю счет 0 для удаленных записей. Мой фильтр вызывает проблему?
Я создал тестовый метод для тестирования моего метода удаления и передаю идентификаторы, чтобы попытаться удалить их.
Тестовое решение
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();
}
Ваш метод ToIdCollection
получает все ids
но также преобразует их из ObjectId
в String
при запуске .Select(dict => dict["_id"].ToString())
. MongoDB сравнивает как значения, так и типы при запуске DeleteManyAsync
и по этой причине нет совпадения - вы пытаетесь сравнить список строк с ObjectIds, которые хранятся в базе данных.
Чтобы исправить это, вы можете заменить ToIdCollection
следующей реализацией:
return @this.Find(Builders<BsonDocument>.Filter.Empty)
.ToEnumerable()
.Select(s => s["_id"].AsObjectId)
.ToList()
IEnumerable<string>
на IEnumerable<ObjectId>
в нескольких местах. Я протестировал этот var filter = Builders<BsonDocument>.Filter.In("_id", ids); var res = Col.DeleteMany(filter);
передавая список ObjectId
и он работает
ToIdCollection
иSetupCollection
? Вы уверены, что запрос и удаление выполняется в одной базе данных / коллекции?