使用'ObjectId'查询MongoDB

时间:2013-01-14 09:15:22

标签: c# .net mongodb mongodb-.net-driver

我已将document插入到没有id的MongoDB中。我想通过搜索已在默认情况下分配MongoDB ObjectId来检索它们。

这是我的尝试 -

var query_id = Query.EQ("_id", "50ed4e7d5baffd13a44d0153");
var entity = dbCollection.FindOne(query_id);
return entity.ToString();

我得到以下错误 -

  

发生了'System.NullReferenceException'类型的第一次机会异常

有什么问题?

5 个答案:

答案 0 :(得分:51)

您需要创建ObjectId的实例,然后使用该实例进行查询,否则您的查询会将ObjectId与字符串进行比较,但无法找到匹配的文档。

这应该有效:

var query_id = Query.EQ("_id", ObjectId.Parse("50ed4e7d5baffd13a44d0153"));
var entity = dbCollection.FindOne(query_id);
return entity.ToString();

答案 1 :(得分:22)

C#中,对于最新的官方 MongoDB.Driver ,请写下这个 -

var filter_id = Builders<MODEL_NAME>.Filter.Eq("id", ObjectId.Parse("50ed4e7d5baffd13a44d0153"));
var entity = dbCollection.Find(filter).FirstOrDefault();
return entity.ToString();

我们可以在不将id从字符串转换为ObjectId的情况下完成相同的结果。但是,我们必须在模型类中的[BsonRepresentation(BsonType.ObjectId)]属性之前添加id

使用 lambda表达式 -

甚至可以进一步简化代码
var entity = dbCollection.Find(document => document.id == "50ed4e7d5baffd13a44d0153").FirstOrDefault();
return entity.ToString();

答案 2 :(得分:2)

所选答案是正确的。对于任何被Query.EQ混淆的人,这是另一种编写基本更新的方法(更新整个mongodb文档):

string mongoDocumentID = "123455666767778";
var query = new QueryDocument("_id", ObjectId.Parse(mongoDocumentID)); 
var update = new UpdateDocument { { "$set", documentToSave } };
mongoCollection.Update(query, update, UpdateFlags.Multi);

当您想要按对象ID实际搜索时,需要ObjectId对象,否则它将字符串与objectid类型进行比较,并且它将不匹配。无论字段名称是否正确,Mongo都是以这种方式严格的类型。

答案 3 :(得分:2)

如果您在2018年在这里并且想要复制/粘贴仍可使用的代码或纯字符串语法;

    [Fact]
    public async Task QueryUsingObjectId()
    {
        var filter = Builders<CosmosParkingFactory>.Filter.Eq("_id", new ObjectId("5b57516fd16cb04bfc35fcc6"));
        var entity = stocksCollection.Find(filter);
        var stock = await entity.SingleOrDefaultAsync();
        Assert.NotNull(stock);

        var idString = "5b57516fd16cb04bfc35fcc6";
        var stringFilter = "{ _id: ObjectId('" + idString + "') }";
        var entityStringFiltered = stocksCollection.Find(stringFilter);
        var stockStringFiltered = await entityStringFiltered.SingleOrDefaultAsync();
        Assert.NotNull(stockStringFiltered);
    }

答案 4 :(得分:0)

您也可以这样做

public static ObjectId GetInternalId(string id)
    {
        if (!ObjectId.TryParse(id, out ObjectId internalId))
            internalId = ObjectId.Empty;

        return internalId;
    }

然后在您的方法中,您可以执行以下操作

ObjectId internalId = GetMongoId.GetInternalId(id);
        return await YourContext.YourTable.Find(c => c.InternalId == internalId).FirstOrDefaultAsync();

注意:GetInternalId中的id参数是该方法的参数。如果您需要这样:

public async Task<YourTable> Find(string id)
    {
        ObjectId internalId = GetMongoId.GetInternalId(id);
        return await YourContext.YourTable.Find(c => c.InternalId == internalId).FirstOrDefaultAsync();
    }

希望它也有帮助。