简体   繁体   中英

how to read back out the auto generated ID from mongo after insertion using official c# driver?

after you insert a new document into mongodb via the official c# driver, how to you immediately read back the generated _id so I can use it as a "foreign" key to other collections? i know in sql server i can immediately read back the identity column value for the newly inserted row, so i need the similar functionality in mongodb.

since the _id generated by mongo isn't an actual member of the object, assume you need to do something with the generic bsondocument?

You can do an upsert with the findAndModify command to achieve this same effect with less work than going through generating your own id's. (Why bother, there is a very good reason 10gen decided on the sceme that is used -- it enables easy sharding)

The findAndModify command lets you find or upsert (create if it doesn't exist) a document and return that same document.

The general form is as follows:

db.runCommand( { findAndModify : <collection>, <options> } )

You can read more about it here .

You would want to use the new in addition to the upsert option so that you get back the newly created object.

In MongoDB, ids are (usually) generated on client side. And you can generate one yourself, using appropriate driver call, put in into document and it'll get saved.

I didn't work with C# driver, but Ruby driver does all the work for me.

ruby-1.9.3-p0 :027 >   obj = coll.insert({'foo' => 'bar'})
 => BSON::ObjectId('4ef15e7f0ed4c00272000001') 
ruby-1.9.3-p0 :030 > coll.find.to_a
 => [{"_id"=>BSON::ObjectId('4ef15e7f0ed4c00272000001'), "foo"=>"bar"}] 

This is how I can make a new ID

ruby-1.9.3-p0 :039 >   newid = BSON::ObjectId.new
 => BSON::ObjectId('4ef15f030ed4c00272000002') 
ruby-1.9.3-p0 :040 > coll.insert({_id: newid, test: 'test'})
 => BSON::ObjectId('4ef15f030ed4c00272000002') 
ruby-1.9.3-p0 :041 > coll.find.to_a
 => [{"_id"=>BSON::ObjectId('4ef15e7f0ed4c00272000001'), "foo"=>"bar"},     {"_id"=>BSON::ObjectId('4ef15f030ed4c00272000002'), "test"=>"test"}] 

如果需要_id,则可以自己生成它,并在文档上手动进行设置。

In most drivers the _id field is actually generated on the client side before going to the server. MongoDB does not use an "auto-increment" ID, so you can actually generate a random ID and tell the server "use this" .

In C# the code looks like this:

var id = ObjectId.GenerateNewId();

So you can create a BSON document and simply save it:

var toSave = new BsonDocument {
    { "_id", ObjectId.GenerateNewId() },
    { "data", "my data" }
};
db.collection.Save(toSave);

However, by default, when you .Save() a document this will update the _id field. So you can generally just save the BSONDocument ( or BSONSerializable class ) and then read it back.

Note that there is a specification called DBRef that helps simplify the implementation of "Foreign Keys". The docs are here , in C# you will want to look at the DBRef class.

Like the other answers here say, IDs are assigned client-side. Something you can do is create a default value convention that generates a new ID during insert if it hasn't been set yet.

public class DefaultValueConvention : MongoDB.Bson.Serialization.Conventions.IDefaultValueConvention
{
    public object GetDefaultValue(MemberInfo memberInfo)
    {
        var type = memberInfo.MemberType == MemberTypes.Property
                       ? ((PropertyInfo) memberInfo).PropertyType
                       : ((FieldInfo) memberInfo).FieldType;

        if (type.IsSubclassOf(typeof(ObjectId)))
            return ObjectId.GenerateNewId();
        else
            return null;
    }
}

And setup the driver to use this convention:

var profile = new ConventionProfile();
profile.SetDefaultValueConvention(new DefaultValueConvention());
BsonClassMap.RegisterConventions(profile, x => x.FullName.StartsWith("ConsoleApplication"));

So now you can create an object & persist it in 2 lines:

var animal = new Animal {Name = "Monkey", PercentDeviationFromHumans = 2.01};
db["animals"].Save(animal);

Actually, with the most recent driver you don't even need to set the default value convention, it already has this behavior OOTB. Regardless, conventions are underused in mongo.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM