33

我已经将documents 插入到 MongoDB 中而没有id. 我想通过搜索他们的MongoDB来检索它们,这是ObjectId默认分配的。

这是我的尝试-

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

我得到以下错误 -

发生“System.NullReferenceException”类型的第一次机会异常

问题是什么?

4

5 回答 5

64

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

这应该有效:

var query_id = Query.EQ("_id", ObjectId.Parse("50ed4e7d5baffd13a44d0153"));
var entity = dbCollection.FindOne(query_id);
return entity.ToString();
于 2013-01-14T09:30:32.473 回答
33

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从 string 转换为ObjectId. 但是,我们将不得不在模型类中添加[BsonRepresentation(BsonType.ObjectId)]beforeid属性。

甚至可以使用lambda 表达式进一步简化代码-

var entity = dbCollection.Find(document => document.id == "50ed4e7d5baffd13a44d0153").FirstOrDefault();
return entity.ToString();
于 2016-02-07T10:25:29.640 回答
4

如果您在 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);
    }
于 2018-07-27T14:14:41.327 回答
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 在这种方式下对类型非常严格,无论字段名称是否正确。

于 2014-01-24T00:26:45.130 回答
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();
    }

希望它也有帮助。

于 2018-08-21T20:57:36.440 回答