[英]how to read back out the auto generated ID from mongo after insertion using official c# driver?
通过官方C#驱动程序将新文档插入mongodb后,如何立即回读生成的_id,以便将其用作其他集合的“外键”? 我知道在sql server中,我可以立即读回新插入行的标识列值,因此我需要在mongodb中使用类似的功能。
由于mongo生成的_id不是对象的实际成员,因此假设您需要对通用bsondocument做些事情?
您可以使用findAndModify命令进行upsert,以比生成自己的id少的工作来达到相同的效果。 (为什么要打扰,有一个很好的理由使10gen决定要使用的sceme,它使分片变得容易)
findAndModify命令使您可以查找或追加(如果不存在,则创建)文档并返回该文档。
一般形式如下:
db.runCommand( { findAndModify : <collection>, <options> } )
您可以在此处了解更多信息。
除了upsert选项外,您还想使用new对象,以便取回新创建的对象。
在MongoDB中,通常是在客户端生成ID。 然后,您可以使用适当的驱动程序调用自己生成一个文件,并将其放入文档中,然后将其保存。
我没有使用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"}]
这是我可以制作新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,则可以自己生成它,并在文档上手动进行设置。
在大多数驱动程序中, _id
字段实际上是在转到服务器之前在客户端生成的。 MongoDB不使用“自动递增” ID,因此您实际上可以生成一个随机ID并告诉服务器“使用此” 。
在C#中,代码如下所示:
var id = ObjectId.GenerateNewId();
因此,您可以创建一个BSON文档并简单地保存它:
var toSave = new BsonDocument {
{ "_id", ObjectId.GenerateNewId() },
{ "data", "my data" }
};
db.collection.Save(toSave);
但是,默认情况下,当您.Save()
文档时,这将更新_id
字段。 因此,您通常可以只保存BSONDocument
( 或BSONSerializable
类 ),然后将其读回。
请注意,有一个名为DBRef的规范可以帮助简化“外键”的实现。 文档在这里 ,在C#中,您将要查看DBRef
类。
就像这里的其他答案一样,ID是在客户端分配的。 您可以做的是创建一个默认值约定,如果尚未设置,它将在插入过程中生成一个新的ID。
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"));
现在,您可以创建一个对象并将其保留为两行:
var animal = new Animal {Name = "Monkey", PercentDeviationFromHumans = 2.01};
db["animals"].Save(animal);
实际上,对于最新的驱动程序,您甚至不需要设置默认值约定,它已经具有此行为OOTB。 无论如何,在mongo中未充分使用约定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.