当我有一个包含文档列表的根文档并且我保存/插入时,根文档总是从MongoDB获取一个ID,但列表中的文档没有,它们与{{1}保持一致}。我不确定我做错了什么或者这是否是预期的行为?
这是我正在尝试做的一个例子: 鉴于课程:
ObjectId.Empty
有工厂:
public class Foo
{
public ObjectId Id { get; set; }
public string Name { get; set; }
public IList<Bar> Bars { get; set; }
}
public class Bar
{
public ObjectId Id { get; set; }
public string Name { get; set; }
}
当我运行这样的样本时:
public class Factory
{
public Foo CreateFoo(string name)
{
return new Foo {
Id = new ObjectId(),
Name = name,
Bars = new List<Bar>()
};
}
public Bar CreateBar(string name)
{
return new Bar {
Id = new ObjectId(),
Name = name
};
}
}
MongoDB生成的public class Program
{
static void Main(string[] args)
{
var client = new MongoClient("mongodb://localhost");
var server = client.GetServer();
var database = server.GetDatabase("Example1");
if (!database.CollectionExists("foos")) database.CreateCollection("foos");
var factory = new Factory();
var foo1 = factory.CreateFoo("first");
foo1.Bars.Add(factory.CreateBar("bar"));
var collection = database.GetCollection("foos");
collection.Insert(foo1);
var foo2 = factory.CreateFoo("second");
collection.Insert(foo2);
foo2.Bars.Add(factory.CreateBar("bar"));
collection.Save(foo2);
}
}
和foo1
都得到了foo2
,但_id
都没有。所有Bars
仍然拥有Bars
。现在一个简单的解决方案是更新工厂以使用ObjectId.Empty
,但我觉得从数据库生成它更舒服。有没有人对此有任何见解?难道我做错了什么?这甚至可能吗?感谢您的投入。
答案 0 :(得分:1)
这是预期的行为。每个文档(不是子文档)都有一个_id,如果为空则自动分配。
您需要拥有单独的Bars集合并从Foo文档中引用它,或者手动生成ObjectIds。
如果您是从工厂[或存储库]进行的,那么它就会很稳固。
编辑:
另外,如果您使用
[BsonRepresentation(BsonType.ObjectId)]
string Id {get;set;}
这意味着您可以更轻松地访问objectId值,它仍然可以保存为ObjectId。
答案 1 :(得分:1)
当字段被标识为集合的_id
时,驱动程序将仅为您生成Id字段。在您的情况下,Bar
嵌入在Foo
文档中。
因此,Bar
拥有自动生成的Id字段是没有意义的。
在您的示例中,Bar
没有理由拥有唯一的_id
。查询集合时,您将根据_id
的{{1}}进行查询,并在响应中提供Foo
个对象。
这绝对是预期的行为。
答案 2 :(得分:0)
有一种常见方案可以更新或删除嵌入文档集合的一个元素。唯一的方法是依靠id。
目前我已经构建了一个自定义的IIdGenerator并将其分配给了IdMemberMap,但只调用了根文档。
是否有其他方法可以为嵌入文档生成自动ID?