假设我有一个产品列表。当我添加一个新产品时,我会使用类似以下的方法保存它:
var doc=products.Insert<ProductPDO>(p);
问题在于完成后我想将用户重定向到该产品的页面。因此,我需要重定向到 /products/<ObjectID>
。但是,我没有找到一种不手动查询数据库并查找具有所有相同字段的文档的方法来立即获取 ObjectID。 是否有更简单的方法?(同时,在这种情况下,doc
返回 null,原因未知)
假设我有一个产品列表。当我添加一个新产品时,我会使用类似以下的方法保存它:
var doc=products.Insert<ProductPDO>(p);
问题在于完成后我想将用户重定向到该产品的页面。因此,我需要重定向到 /products/<ObjectID>
。但是,我没有找到一种不手动查询数据库并查找具有所有相同字段的文档的方法来立即获取 ObjectID。 是否有更简单的方法?(同时,在这种情况下,doc
返回 null,原因未知)
Insert
方法会自动设置已声明为模型BSON ID的属性。
如果如下声明...
[BsonId]
public ObjectId Id { get; set; }
如果将对象插入到集合中,则Id
字段将包含对象的默认(新的、唯一的)BSON ID:
coll.Insert(obj);
// obj.Id is now the BSON ID of the object
data = {
title: "Howdy"
}
那么当我们将数据对象插入数据库时
db.collection('collectionName', function(err, collection) {
collection.insert(data);
console.log(data._id); // <- The mongodb id is now set on the item
});
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string id { get; set; }
使用:
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
当您插入对象时,Mongo会将文档的ID返回到模型的ID字段中。
public static TId GetId<TId>(this BsonDocument document) where TId : struct
{
if (document == default(BsonDocument))
{
throw new ArgumentNullException("document");
}
var id = document["_id"];
object idAsObject;
if (id.IsGuid)
{
idAsObject = (object)id.AsGuid;
}
else if (id.IsObjectId)
{
idAsObject = (object)id.AsObjectId;
}
else
{
throw new NotImplementedException(string.Format("Unknown _id type \"{0}\"", id.BsonType));
}
var idCasted = (TId)idAsObject;
return idCasted;
}
使用方法如下:
Guid idOfDoc = myBsonDocument.GetId<Guid>();
尽管如此,您应该更喜欢选择答案中的专用属性...
在持久化之前,我将自定义类型 T
转换为 BsonDocument
。
var bsonDocument = item.ToBsonDocument();
_mongoCollection.InsertOne(bsonDocument);
T
has a property Id:
[BsonId]
public ObjectId Id { get; set; }
ToBsonDocument()
方法时,Id
字段会被填充为ObjectId
,然后推送到Mongo DB。这个方法会在代码中自己创建ID,而不是委托给Mongo DB来创建。但对我的情况来说已经足够了。"最初的回答"class BsonID
{
[BsonId]
public ObjectId Id { get; set; }
}
var document = new BsonDocument {
{"_id", new BsonID().Id },
{ "code", dr.Cells["code"].Value.ToString() },
{ "name", dr.Cells["name"].Value.ToString() },
};
var customers = _database.GetCollection<BsonDocument>("Customers");
customers.InsertOne(document);
var id = document.ElementAt(0).Value.ToString();
将Class.Type作为BsonDocument而不是真正的Class.Type可能是此问题的常见原因:
e.g.:
var stream = mDB.GetCollection<vStreamMessage>(dictINI[sMONGODB_COLLECTION_NAME]);
stream.InsertOne(msg);
不是
var stream = mDB.GetCollection<**BsonDocument**>(dictINI[sMONGODB_COLLECTION_NAME]);
stream.InsertOne(**msg.ToBsonDocument**);
2021年:如果您正在使用C#9中的MongoDb和record
s,您可以使用以下技巧来获取插入的ID:
private async Task<T> AddEntity<T>(T entity, string collectionName) where T: EntityBase
{
var col = _db.GetCollection<BsonDocument>(collectionName);
var document = entity.ToBsonDocument();
document["_id"] = ObjectId.Empty;
await col.InsertOneAsync(document);
var insertedEntity = entity with
{
id = document["_id"].ToString()!
};
return insertedEntity;
}
EntityBase
是您所有文档的基本实体,具有 id
字段。或者,您可以选择不使用泛型。
InsertManyAsync
时,发现调用后C#对象中的ID没有被填充。我一开始传递了一个LINQSelect
(IEnumerable<>
)的结果,但是后来改为传递了一个List<>
,现在ID已经被填充了。请参考https://stackoverflow.com/questions/42605122/c-sharp-mongodb-insertmany-missing-id-after-insert。 - draketb