如何使用官方c#驱动程序从mongo读取插入后自动生成的ID?
在通过官方c#驱动程序将新文档插入mongodb后,如何立即读回生成的#id,以便我可以将其用作其他集合的“外键”?我知道在sql server中,我可以立即读回新插入行的标识列值,因此我需要mongodb中的类似功能 由于mongo生成的_id不是对象的实际成员,因此假设您需要对MongoDB中的通用bsondocument?执行某些操作,id(通常)是在客户端生成的。您可以自己生成一个,使用适当的驱动程序调用,放入文档中,然后保存 我没有使用C#驱动程序,但Ruby驱动程序为我完成了所有工作如何使用官方c#驱动程序从mongo读取插入后自动生成的ID?,c#,mongodb,driver,C#,Mongodb,Driver,在通过官方c#驱动程序将新文档插入mongodb后,如何立即读回生成的#id,以便我可以将其用作其他集合的“外键”?我知道在sql server中,我可以立即读回新插入行的标识列值,因此我需要mongodb中的类似功能 由于mongo生成的_id不是对象的实际成员,因此假设您需要对MongoDB中的通用bsondocument?执行某些操作,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,您可以自己生成并在文档上手动设置。在大多数驱动程序中,
\u 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()
文档时,这将更新\u id
字段。因此,您通常只需保存BSONDocument
(或BSONSerializable
类),然后将其读回即可
请注意,有一个名为DBRef的规范可以帮助简化“外键”的实现。文档是,在C#中,您将希望查看
DBRef
类。您可以使用findAndModify命令执行upsert,以比生成自己的id更少的工作量实现相同的效果。(何必麻烦呢,10gen决定使用sceme有一个很好的理由——它支持轻松的切分)
findAndModify命令允许您查找或上传(如果不存在则创建)一个文档并返回该文档
一般形式如下:
db.runCommand( { findAndModify : <collection>, <options> } )
db.runCommand({findAndModify:,})
你可以阅读更多关于它的内容
除了upsert选项之外,您还需要使用new,以便返回新创建的对象。与这里的其他答案一样,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);
实际上,对于最新的驱动程序,您甚至不需要设置默认值约定,它已经有了这种行为。不管怎样,传统在mongo中使用不足