繁体   English   中英

使用官方C#驱动程序插入后,如何从mongo中读出自动生成的ID?

[英]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字段。 因此,您通常可以只保存BSONDocumentBSONSerializable ),然后将其读回。

请注意,有一个名为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.

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