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");
我是 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");