MongoDB C# - LINQ 包含针对字符串数组抛出 ArgumentException

MongoDB C# - LINQ Contains against a string array throws ArgumentException

我是 MongoDB 的新手,所以这可能是一个天真的问题,但我还没有通过谷歌搜索找到任何 relevant/up 的最新信息:我正在尝试使用 MongoDB C# 驱动程序(版本 2.2.4)从接收到的 filter POCO 对象组成一个基于 LINQ 的查询,一次一个,如下所示:

IQueryable<BsonDocument> parts = collection.AsQueryable();
if (filter.Name != null)
    parts = parts.Where(d => d["Name"].Equals(filter.Name));
// ... etc; I'll then call ToList() to get results ...

现在,我的 filter 属性之一是一个字符串数组,这意味着我应该匹配字段为 Vendor 的任何文档(MongoDB 中的字符串 属性 document) 等于数组中的任何字符串(如 MongoDB native $in: https://docs.mongodb.com/manual/reference/operator/query/in/)。

为此,我尝试使用 Contains(1 维数组的特殊情况只是一种优化):

if (filter.Vendors != null && filter.Vendors.Length > 0)
{
    parts = filter.Vendors.Length == 1
        ? parts.Where(d => d["Vendor"].Equals(filter.Vendors[0]))
        : parts.Where(d => filter.Vendors.Contains(d["Vendor"].AsString));
}

这会编译,但会抛出一个 ArgumentException:"Expression of type 'MongoDB.Bson.BsonValue' cannot be used for parameter of type 'System.String' of method 'Boolean Contains[String](System.Collections.Generic.IEnumerable`1[System.String], System.String)'"。

http://mongodb.github.io/mongo-csharp-driver/2.2/reference/driver/crud/linq/,没有Contains$in;然而,从 https://jira.mongodb.org/browse/CSHARP-462 看来,驱动程序现在应该能够处理该方法。

顺便说一句,如果我将代码稍微更改为:

,也会发生同样的情况
   parts.Where(d => filter.Vendors.Any(s=> d["Vendor"].Equals(s)));

根本不涉及Contains。异常消息抱怨无法将 BsonValue 用于 string,但 BsonValue 是正确的 string。谁能提出解决方案?

异常消息围绕完全拥抱 BsonValue 让 mongo 处理类型而不是尝试转换为 string 的想法跳舞。我让它工作,供应商类型为 List<BsonValue>

class Filter
{ 
        public List<BsonValue> Vendors { get; set; }
}

...

var list = parts.Where(d => filter.Vendors.Contains(d["Vendor"]));
foreach (var document in list)
{
    Console.WriteLine(document["Name"]);
}

另一种方法是将您的文档映射到 C# class 而不是使用 BsonDocument 作为集合类型。

class MyDocument
{
    public ObjectId Id { get; set; }
    public string Name { get; set; }
    public string Vendor { get; set; }
}
...
var collection = db.GetCollection <MyDocument> ("parts");