我正在使用官方C#MongoDb强类型驱动程序版本2.7.0-beta001与Windows 10计算机上的MongoDB v 4.0-rc1进行交互。
考虑以下课程:
public class Library
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public DateTime DateAdded { get; set; }
public DateTime LastModified { get; set; }
public string Title { get; set; }
public Author Author { get; set; }
public bool AllBooks { get; set; }
}
public class Author {
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string BirthDate { get; set; }
public string ScientificDegree { get; set; }
public List<Book> Books { get; set; }
}
public class Book
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Title { get; set; }
public int PublishYear { get; set; }
public string Content { get; set; }
public bool IsVerified { get; set; }
}
如果所有作者书籍都经过验证,如何更新库文档,这是我的代码:
string libraryId = GetLibraryId();
var repository = _database.GetCollection<Library>("Libraries");
var filter = Builders<Library>.Filter.Where(l => l.Id == libraryId &&
l.Author.Books.All(b => b.IsVerified == true));
var update = Builders<Library>.Update.Set(l => l.AllBooks, true);
await repository.UpdateOneAsync(filter, update);
最后一行抛出System.ArgumentException:Unsupported filter:All
答案 0 :(得分:1)
在您的POCO类中,Books
是一个.NET列表,因此您可以(理论上)使用所有扩展方法(如All
)。问题是它不是对象的LINQ,所以这个表达式不在内存中计算。 MongoDB驱动程序正在尝试将其转换为MongoDB查询,因为您可以看到MongoDB查询语言中没有相应的运算符。
你能做什么?您可以尝试将此过滤器重写为其他内容(保持相同的逻辑含义)。例如,您可以使用$elemMatch。您可以构建查询,尝试查找至少有一本等于false的图书的文档,然后使用IsVerified
来否定该条件,而不是尝试查找$not
等于true的所有图书。在这种情况下,$elemMatch
有用:
$ elemMatch运算符将包含数组字段的文档与至少一个元素匹配,该元素与所有指定的查询条件匹配。
至少一个 意味着无。
然后你的代码看起来像这样:
var col = mydb.GetCollection<Library>("Libraries");
var filter = Builders<Library>.Filter.Not(
Builders<Library>.Filter.ElemMatch(x => x.Author.Books, b => b.IsVerified == false));
var update = Builders<Library>.Update.Set(l => l.AllBooks, true);
await col.UpdateManyAsync(filter, update);