2017-07-25 57 views
2
interface Nameable 
{ 
    string Name { get; set; } 
} 

class Parent : Nameable 
{ 
    public string Name { get; set; } 

    public List<Child> Children { get; set; } = new List<Child>(); 
} 

class Child 
{ 
    public string Name { get; set; } 

    public int Value { get; set; } 

    public string DataOne { get; set; } 

    public string DataTwo { get; set; } 

    public double DataThree { get; set; } 
} 



    static async void MainAsync(string[] args) 
    { 
     for (int i = 0; i < random.Next(10000, 50000); i++) 
     { 
      Parents.Add(CreateParent()); 
     } 

     Parents = Parents.GroupBy(g => g.Name).Select(grp => grp.First()).ToList(); 

     foreach (var parent in Parents) 
     { 
      await Insert<Parent>(parent); 
     } 

     // update objects randomly; 

     foreach (var parent in Parents) 
     { 
      for (int i = 0; i < random.Next(10, 30); i++) 
      { 
       int decision = random.Next(0, 2); 

       if (decision == 0 && parent.Children.Count > 0) 
       { 
        parent.Children.RemoveAt(random.Next(0, parent.Children.Count)); 
       } 
       else 
       { 
        var inner = CreateChild(); 
        if (!parent.Children.Any(io => io.Name == inner.Name)) 
        { 
         parent.Children.Add(inner); 
        } 

       } 

       await ReplaceOne<Parent>(parent); 
      }    
     } 
    } 

我有一個父項列表,每個列表包含子元素列表。當使用c#Mongo驅動程序通過刪除或添加新的孩子更新這些父母后,儘管在代碼調用replace方法時沒有重複,它有時會在Mongo方面創建Child的重複項。Mongo替換導致子文檔c中的重複項#

我認爲這與Mongo的原子文檔結構以及它如何更新/替換項目有關。有沒有辦法來防止這個創建重複?如果它不是由於原子性質造成的,是什麼造成了這種情況? 編輯:

static async Task ReplaceOne<T>(T obj) 
     where T : Nameable 
    { 
     await database.GetCollection<T>(typeof(T).Name).ReplaceOneAsync(Builders<T>.Filter.Where(t => t.Name == obj.Name), obj); 
    } 

    static async Task Insert<T>(T obj) 
    { 
     await database.GetCollection<T>(typeof(T).Name).InsertOneAsync(obj); 
    } 

    static Parent CreateParent() 
    { 
     var innerObjects = new List<Child>(); 
     for (int i = 0; i > random.Next(1, 10); i++) 
     { 
      innerObjects.Add(CreateChild()); 
     } 

     return new Parent() 
     { 
      Name = RandomString(), 
      Children = innerObjects 
     }; 
    } 

    static Child CreateChild() 
    { 
     return new Child() 
     { 
      Name = RandomString(), 
      Value = RandomInt(), 
      DataOne = RandomString(), 
      DataTwo = RandomString(), 
      DataThree = RandomDouble() 
     }; 
    } 

添加替換/插入片段,他們使用的是蒙戈C#驅動程序插入到數據庫。 CreateParent和CreateChild只是用隨機相關數據填充對象。

+0

CreateParent,CreateChild,Insert和ReplaceOne方法是什麼樣的? – dnickless

+0

創建父/子只需用隨機數據填充子/父類。插入使用Mongo C#驅動程序插入到Mongo並替換它替換它,可以發佈方法作爲編輯明天早上 – Jack

回答

1

我試圖猜測你的RandomString()RandomInt()RandomDouble()方法,我運行你的項目幾次而沒有清理數據庫。根據兩個「名稱」屬性(父母和子女),我無法檢測到任何重複內容。

我懷疑你的觀察是不正確的。爲了檢查你是否確實在同一個家長中有重複的孩子,你可以使用以下查詢:

collection.aggregate(
{ 
    $unwind: "$Children" 
}, 
{ 
    $group: 
    { 
     _id: 
     { 
      "Name": "$Name", 
      "ChildName": "$Children.Name" 
     } 
     , "count": { $sum: 1 } 
    } 
}, 
{ 
    $match: 
    { 
     "count": { $ne: 1 } } 
    } 
) 
+0

檢查了我的聚合,看起來像我有一個類型,導致它出現像有重複時通過計數不是。謝謝 – Jack