我有以下 C# 模型类:
public class Thingy
{
public ObjectId Id { get; set; }
public string Title { get; set; }
public DateTime TimeCreated { get; set; }
public string Content { get; set; }
public string UUID { get; set; }
}
以及以下 ASP.MVC Controller 操作:
public ActionResult Create(Thingy thing)
{
var query = Query.EQ("UUID", thing.UUID);
var update = Update.Set("Title", thing.Title)
.Set("Content", thing.Content);
var t = _collection.Update(query, update, SafeMode.True);
if (t.UpdatedExisting == false)
{
thing.TimeCreated = DateTime.Now;
thing.UUID = System.Guid.NewGuid().ToString();
_collection.Insert(thing);
}
/*
var t = _collection.FindOne(query);
if (t == null)
{
thing.TimeCreated = DateTime.Now;
thing.UUID = System.Guid.NewGuid().ToString();
_collection.Insert(thing);
}
else
{
_collection.Update(query, update);
}
*/
return RedirectToAction("Index", "Home");
}
此方法执行更新或插入。如果需要执行插入操作,则必须设置 UUID 和 TimeCreated 成员。如果需要更新,则必须保留 UUID 和 TimeCreated,但必须更新成员 Title 和 Content。
注释掉的代码可以工作,但似乎不是最有效的。当它调用 FindOne 时,即访问 mongodb 一次。然后,如果它转到 else 子句,它会执行另一个查询和更新操作,因此又需要 2 次访问 mongodb。
什么是更有效的方法来完成我想要完成的任务?
最佳答案
正如链接的 SO 答案中提到的,要使更新插入工作,您需要更新整个文档,而不仅仅是一些属性。
我个人会将创建
和编辑
分成单独的MVC操作。建议零售价。创建 Thingy
与更新它有不同的考虑因素。
如果您仍然想执行更新插入而不是单独的插入/更新调用,则需要使用以下代码:
_collection.Update(
Query.EQ("UUID", thing.UUID),
Update.Replace(thing),
UpsertFlags.Upsert
);
现在的问题是,我们如何确保事物
对于两种情况(即插入和更新)具有适当的值。
我的假设是(基于您的代码模型绑定(bind)到 Thingy
实例),您的 View 正在发送回所有字段(包括 UUID
和 TimeCreated
)。这意味着,在更新的情况下, View 已经预先填充了 UUID
和 TimeCreated
的值。因此,在更新 Thingy
的情况下,thing
对象具有最新值。
现在,在创建 View 时,呈现 View 时,您可以为 TimeCreated
字段存储 DateTime.MinValue
。在 Create
MVC 操作中,您可以检查 TimeCreated
是否为 DateTime.MinValue
,然后将其设置为当前时间,并为UUID
。
这样,在插入的情况下,事物
也具有最新值。因此我们可以安全地进行更新插入。
关于c# - 在 mongodb 中执行高效的更新插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12460005/