首页 > 解决方案 > C# Mongo 驱动程序:使用联接和 UpdateManyAsync 更新查询

问题描述

我有 2 个收藏

产品分类

_id 名称活动

产品

_id CategoryId DateUpdated

我可以通过创建过滤器并使用 UpdateManyAsync 在一个集合中进行更新,如下所示:

var update = Builders<ProductCategory>.Update
                .Set(x => x.Active ,false);


var filter = Builders<ProductCategory>.Filter.Where(
                x => x.Active == true);

var result = await Collection.UpdateManyAsync(filter, update);

现在,如果与当前日期相比 DateUpdated 超过 1 天的任何文档,我想更新 ProductCategory 上的 Active 字段

它可能与 sql 查询相同:

UPDATE A
SET active = false
FROM ProductCategory A
JOIN Product B
    ON A._id= B.CategoryId
WHERE DATEDIFF(Getdate(), B.DateCreated) >= 1

标签: c#mongodb

解决方案


afaik 您无法通过单个命令根据 mongodb 中的查找/加入结果更新实体。相反,您必须先检索类别的 ID,然后执行如下更新操作:

var inactiveCatIDs = collection.AsQueryable()
                               .Where(p => p.DateUpdated <= DateTime.UtcNow.AddDays(-1))
                               .Select(p => p.CategoryID)
                               .ToArray();

collection.UpdateMany(c => inactiveCatIDs.Contains(c.ID),
                      Builders<ProductCategory>.Update.Set(c => c.Active, false));

这是一个测试程序:

using MongoDB.Entities;
using MongoDB.Entities.Core;
using System;
using System.Linq;

namespace StackOverflow
{
    public class Product : Entity
    {
        public DateTime DateUpdated { get; set; }
        public string CategoryID { get; set; }
    }

    public class ProductCategory : Entity
    {
        public bool Active { get; set; }
    }

    public class Program
    {
        private static void Main(string[] args)
        {
            new DB("test", "localhost");

            var cat1 = new ProductCategory { Active = true }; cat1.Save();
            var cat2 = new ProductCategory { Active = true }; cat2.Save();

            (new[] { new Product
            {
                CategoryID = cat1.ID,
                DateUpdated = DateTime.UtcNow.AddDays(-1.5)
            },
            new Product
            {
                CategoryID = cat2.ID,
                DateUpdated = DateTime.UtcNow
            }}).Save(); ;

            var inactiveCatIDs = DB.Queryable<Product>()
                                   .Where(p => p.DateUpdated <= DateTime.UtcNow.AddDays(-1))
                                   .Select(p => p.CategoryID)
                                   .ToArray();

            DB.Update<ProductCategory>()
              .Match(c => inactiveCatIDs.Contains(c.ID))
              .Modify(c => c.Active, false)
              .Execute();
        }
    }
}


推荐阅读