首页 文章

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

提问于
浏览
1

我是MongoDB的新手,所以这可能是一个天真的问题,但我没有通过Google搜索找到任何相关/最新信息:我正在尝试使用MongoDB C#驱动程序(版本2.2.4)来编写LINQ-基于查询,一次一件,来自收到的 filter POCO对象,如下所示:

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文档中的字符串属性)等于数组中的任何字符串(如MongoDB native $inhttps://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 . 有人可以提出解决方案吗?

1 回答

  • 0

    异常消息围绕着完全拥抱 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#类,而不是使用BsonDocument作为集合类型 .

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

相关问题