【问题标题】:C# MongoDB update definition from filled modelC# MongoDB 从填充模型更新定义
【发布时间】:2020-12-26 20:22:47
【问题描述】:

我如何结合类型 C# 填充模型和 mongo 语言来创建更新请求?

我试试这个,但得到类型错误:

 var update = new ObjectUpdateDefinition<User>(user) & Builders<User>.Update.Inc(f => f.FindCount, 1);

完整代码:

            var user = new Model
            {
                Email = email,
                Language = language,
                Password = password,
                // +17 fields
            };
            
            // how i can convert all fields to set? and join with query Inc (like AllFieldToSet)? 
            var update = user.AllFieldToSet() & Builders<User>.Update.Inc(f => f.FindCount, 1);
            
            Models.FindOneAndUpdate<Model>(
             f => f.Email == email, 
             update, 
             new FindOneAndUpdateOptions<Model> {IsUpsert = true});

【问题讨论】:

    标签: c# mongodb mongodb-query mongodb-.net-driver


    【解决方案1】:

    首先我会问为什么要一次更新这么多字段,这会对性能和可伸缩性产生重大影响,尤其是当您的集合涉及索引、复制和/或分片时。每当您必须更新索引字段时,它也需要更新索引。

    有多种解决方案:

    替换一个: Inc只增加值,这可以在模型中手动完成:FindCount++

    手动构建更新操作符:只需使用他们提供的构建器手动构建

    使用反射编写你自己的扩展我个人喜欢类型安全,但你可以使用我编写的这个扩展(你只需要扩展它并构建空检查等)

    public static class UpdateBuilderExtensions
    {
        public static UpdateDefinition<TDocument> SetAll<TDocument, TModel>(this UpdateDefinition<TDocument> updateBuilder, TModel value, params string[] excludeProperties)
        {
            foreach (var property in value.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => excludeProperties?.Contains(x.Name) == false))
                updateBuilder = Builders<TDocument>.Update.Combine(updateBuilder.Set(property.Name, property.GetValue(value)));
    
            return updateBuilder;
        }
    }
    

    它的用法: 您必须排除已经设置的属性,并且必须排除 BsondId 字段(如果您不手动设置)

    var update = Builders<User>.Update.Inc(x => x.FindCount, 1).SetAll(model, nameof(model.Id), nameof(model.FindCount));
    Models.UpdateOne(x => x.Email== "some-email", update, new UpdateOptions
    {
    IsUpsert = true
    });
    

    【讨论】:

    • 因为我需要 .Update.Inc(f => f.FindCount, 1)
    • 更新了我的答案,我认为您只是希望扩展现有的构建器,因此扩展解决方案应该适合您@padavan
    • 谢谢肖恩。这是迄今为止最好的选择。让我们看看还有谁会提供
    • 我发现了新的有趣的东西:ObjectUpdateDefinition(model);但这将 __id 添加到查询中,我得到错误:(
    猜你喜欢
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多