2012-09-17 94 views
2

執行effcient UPSERT我有以下C#模型類:MongoDB中

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控制器動作:

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,但必須更新成員標題和內容。

被註釋掉的代碼有效,但似乎不是最有效的。當它調用FindOne時,這是一次mongodb之旅。然後,如果它轉到else子句,它會執行另一個查詢和更新操作,所以這是mongodb的另外兩次訪問。

什麼是更有效的方法來做我想要完成的事情?

+0

見做upserts時蒙戈[1]在C#MongoDB的upsertting信息採取這種做法。 [1]:http://stackoverflow.com/questions/7240028/upserting-in-mongo-db-using-official-c-sharp-driver – slee

+0

@slee:是的,我看到了和其他來自mongodb網站的參考資料/教程。請重新閱讀我的問題。 –

+0

Mongo徹底改變了他所做的2個dll發佈之間的界面:S – Revious

回答

2

正如在鏈接的SO答案中所提到的,要使upserts正常工作,您需要更新整個文檔,而不僅僅是一些屬性。

我個人會將CreateEdit分隔成單獨的MVC操作。 SRP。創建Thingy與更新它有不同的考慮因素。

如果你還想做一個UPSERT,而不是單獨的插入/更新調用,您需要使用下面的代碼:

_collection.Update(
    Query.EQ("UUID", thing.UUID), 
    Update.Replace(thing), 
    UpsertFlags.Upsert 
); 

現在變成了,我們如何確保thing這個問題有合適的兩種情況下的值,即插入以及更新。

我的假設是(根據您的代碼模型綁定到Thingy實例),您的視圖將發回所有字段(包括UUIDTimeCreated)。這意味着,在更新的情況下,該視圖已經預先填充了UUIDTimeCreated的值。因此,在更新Thingy的情況下,thing對象具有最新值。

現在創建時,當視圖呈現時,您可以爲TimeCreated字段存儲DateTime.MinValue。在您的Create MVC操作中,您可以檢查TimeCreated是否爲DateTime.MinValue,然後將其設置爲當前時間並存儲UUID的新值。

這樣,在插入的情況下,thing具有最新值。我們可以安全地做一個Upsert。

0

我從[使用官方的C#驅動Upserting在蒙戈DB]控制器

public ActionResult Create(Thingy model) 
{ 
    var thing = _collection.FindOneAs<Thingy>(Query.EQ("UUID", model.UUID)); 
    if(thing == null) 
    { 
     thing = new Thingy{ 
         TimeCreated = DateTime.Now, 
         UUID = System.Guid.NewGuid().ToString(), 
         Id = ObjectId.GenerateNewId() 
         } 
    } 
    else 
    { 
     thing.Content = model.Content; 
     //other updates here 
    } 

    _collection.Save<Thingy>(thing); 
    return View(); 
}