Mongo替换导致子文档中的重复c#

时间:2017-07-25 15:17:15

标签: c# mongodb

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驱动程序替换这些父项后,通过删除或添加新子项来更新这些父项有时会在Mongo端创建Child副本,尽管代码调用replace方法时没有重复项。

我认为这与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()
        };
    }

添加了替换/插入片段,他们使用mongo c#驱动程序插入数据库。 CreateParent和CreateChild只是用随机相关数据填充对象。

1 个答案:

答案 0 :(得分:1)

我尝试猜测您的RandomString()RandomInt()RandomDouble()方法,并且我在没有清理数据库的情况下多次运行您的项目。根据两个&#34; Name&#34;我找不到任何重复的内容。属性(在父母和孩子身上)。

我怀疑你的观察是不正确的。为了检查您是否确实在同一父级中有重复的子级,您可以使用以下查询:

collection.aggregate(
{
    $unwind: "$Children"
},
{
    $group:
    {
        _id:
        {
            "Name": "$Name",
            "ChildName": "$Children.Name"
        }
        , "count": { $sum: 1 }
    }
},
{
    $match:
    {
        "count": { $ne: 1 } }
    }
)
相关问题