J'ai inséré document
s dans MongoDB sans id
. Et je veux les récupérer en cherchant dans leur MongoDB ObjectId
, auquel on a attribué par défaut.
Voici ma tentative
var query_id = Query.EQ("_id", "50ed4e7d5baffd13a44d0153");
var entity = dbCollection.FindOne(query_id);
return entity.ToString();
Et j'obtiens l'erreur suivante-
Une exception de première chance du type 'System.NullReferenceException' s'est produite
Quel est le problème?
Vous devez créer une instance de ObjectId
, puis interroger à l'aide de cette instance. Sinon, votre requête compare ObjectId
s à une chaîne et ne parvient pas à trouver les documents correspondants.
Cela devrait fonctionner:
var query_id = Query.EQ("_id", ObjectId.Parse("50ed4e7d5baffd13a44d0153"));
var entity = dbCollection.FindOne(query_id);
return entity.ToString();
Dans C # pour le dernier officiel MongoDB.Driver write this-
var filter_id = Builders<MODEL_NAME>.Filter.Eq("id", ObjectId.Parse("50ed4e7d5baffd13a44d0153"));
var entity = dbCollection.Find(filter).FirstOrDefault();
return entity.ToString();
Nous pouvons obtenir le même résultat sans convertir id
de chaîne en ObjectId
. Mais ensuite, nous devrons ajouter l'attribut [BsonRepresentation(BsonType.ObjectId)]
avant id
dans la classe de modèle.
Le code peut même être encore simplifié en utilisant expression lambda -
var entity = dbCollection.Find(document => document.id == "50ed4e7d5baffd13a44d0153").FirstOrDefault();
return entity.ToString();
Si vous êtes ici en 2018 et que vous souhaitez copier/coller un code qui fonctionne toujours ou une syntaxe de chaîne pure
[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);
}
La réponse sélectionnée est correcte. Pour les personnes confondues par Query.EQ, voici un autre moyen d'écrire une mise à jour de base (met à jour l'ensemble du document mongodb):
string mongoDocumentID = "123455666767778";
var query = new QueryDocument("_id", ObjectId.Parse(mongoDocumentID));
var update = new UpdateDocument { { "$set", documentToSave } };
mongoCollection.Update(query, update, UpdateFlags.Multi);
L'objet ObjectId est nécessaire lorsque vous souhaitez effectuer une recherche par ID d'objet, sinon il compare une chaîne à un type d'objet et ne correspondra pas. Mongo est très strict en ce sens, que le nom du champ soit correct ou non.
Vous pouvez aussi le faire de cette façon, sa
public static ObjectId GetInternalId(string id)
{
if (!ObjectId.TryParse(id, out ObjectId internalId))
internalId = ObjectId.Empty;
return internalId;
}
alors dans votre méthode, vous pouvez faire quelque chose comme ça
ObjectId internalId = GetMongoId.GetInternalId(id);
return await YourContext.YourTable.Find(c => c.InternalId == internalId).FirstOrDefaultAsync();
Remarque: id param dans GetInternalId est un paramètre de cette méthode. Si vous avez besoin de cela:
public async Task<YourTable> Find(string id)
{
ObjectId internalId = GetMongoId.GetInternalId(id);
return await YourContext.YourTable.Find(c => c.InternalId == internalId).FirstOrDefaultAsync();
}
J'espère que ça aide aussi.