相关文章推荐
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I write an extension method to implement the upsert(update if exists else insert) scenario but every time I use it, my records save with "0" object id in my mongodb document. here is my code:

public static async Task<ReplaceOneResult> UpsertAsync<T>
        (this IMongoCollection<T> collection, T entity) where T : IEntity
        return await collection.ReplaceOneAsync(i => i.Id == entity.Id,
            entity,
            new ReplaceOptions { IsUpsert = true });

and my model:

public class User : IEntity
    [BsonId]
    public ObjectId Id { get; set; }
    public int TelegramUserId { get; set; }
    public bool IsBot { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Username { get; set; }
    public string ActivityPath { get; set; }
    public string Number { get; set; }
    public string Location { get; set; }
    public ObjectId [] Playlists { get; set; }

and my saved record looks like this:

"_id": { "$oid": "000000000000000000000000" "TelegramUserId": 515151, "IsBot": false, "FirstName": "Test user", "LastName": null, "Username": "Test", "ActivityPath": null, "Number": null, "Location": null, "Playlists": null}

the problem is "000000000000000000000000" value for id, why id don't init correctly, I expect a valid guid value for that, not just zeros.

thanks for your help.

A MongoId with all zeroes is valid, so the first insert with an all zeroes or "empty" MongoId is not matching on your condition

i => i.Id == entity.Id

causing an insert, but subsequent conditions with an all-zero ID are matching and so they do an update.

Here's what I usually do:

void T Update<T>(T entity) where T : IEntity
    // Id is an ObjectId (which is a .NET struct)
    if (entity.Id == ObjectId.Empty)
        entity.Id = ObjectId.GenerateNewId()

This says, if the ID is the all-zeroes ID (i.e. Empty), generate one (which will be unique; your insert) or keep the existing (your update).

It's a bit more than you asked for on this question, but there's another way to deal with this if you are mapping ObjectId to a string, which occurs in some systems. If that's the case you would do

    // if the Id field is a string that can sometimes be the string version of ObjectId
    entity.Id ??= ObjectId.GenerateNewId().ToString()

when your entity looks something like this

public class User : IEntity
    [BsonId]
    public string Id { get; set; }
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.

 
推荐文章