2017-07-25 42 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