Как прочитать обратно автоматически сгенерированный идентификатор из Монго после вставки с использованием официального драйвера C #? - PullRequest
4 голосов
/ 21 декабря 2011

после того, как вы вставите новый документ в mongodb через официальный драйвер c #, как вы сразу же прочитаете сгенерированный _id, чтобы я мог использовать его как «внешний» ключ для других коллекций?Я знаю, на сервере SQL я могу сразу же прочитать значение столбца идентичности для вновь вставленной строки, поэтому мне нужны аналогичные функции в mongodb.

, поскольку _id, сгенерированный mongo, не является действительным членом объекта, предположим, что вам нужно что-то сделать с универсальным bsondocument?

Ответы [ 5 ]

2 голосов
/ 21 декабря 2011

Вы можете выполнить переход с помощью команды findAndModify, чтобы добиться того же эффекта с меньшими затратами труда, чем при создании собственных идентификаторов. (Зачем беспокоиться, есть очень веская причина, по которой 10gen определился с используемой схемой - она ​​обеспечивает легкое разбиение)

Команда findAndModify позволяет найти или удалить (создать, если он не существует) документ и вернуть тот же документ.

Общая форма выглядит следующим образом:

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

Подробнее об этом можно прочитать здесь .

Вы захотите использовать новый в дополнение к опции upsert, чтобы вернуть вновь созданный объект.

0 голосов
/ 06 февраля 2012

Как и в других ответах здесь, идентификаторы назначаются на стороне клиента. Что-то, что вы можете сделать, это создать соглашение о значении по умолчанию, которое генерирует новый идентификатор во время вставки, если он еще не установлен.

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;
    }
}

И настройте драйвер для использования этого соглашения:

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

Теперь вы можете создать объект и сохранить его в 2 строки:

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

На самом деле, с самым последним драйвером вам даже не нужно устанавливать соглашение о значениях по умолчанию, оно уже имеет такое поведение OOTB. В любом случае, в монго недостаточно используются условные обозначения.

0 голосов
/ 21 декабря 2011

Если вам нужен _id, вы можете сгенерировать его самостоятельно и установить вручную в документе.

0 голосов
/ 21 декабря 2011

В большинстве драйверов поле _id фактически создается на стороне клиента перед переходом на сервер. MongoDB не использует идентификатор «автоинкремента», поэтому вы можете сгенерировать случайный идентификатор и сказать серверу «использовать это» .

В C # код выглядит так:

var id = ObjectId.GenerateNewId();

Таким образом, вы можете создать документ BSON и просто сохранить его:

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

Однако по умолчанию, когда вы .Save() документ, это обновит поле _id. Таким образом, вы можете просто сохранить BSONDocument ( или BSONSerializable class ) и затем прочитать его обратно.

Обратите внимание, что существует спецификация DBRef, которая помогает упростить реализацию «внешних ключей». Документы здесь , в C # вы захотите взглянуть на DBRef класс.

0 голосов
/ 21 декабря 2011

В MongoDB идентификаторы (обычно) генерируются на стороне клиента. И вы можете создать его самостоятельно, используя соответствующий вызов драйвера, вставить в документ, и он будет сохранен.

Я не работал с драйвером C #, но драйвер Ruby делает всю работу за меня.

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"}] 

Вот как я могу сделать новый идентификатор

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"}] 
...