MongoDB - 如何过滤和更新子级的子级

问题描述 投票:0回答:1

我正在使用 C# 和 MongoDB:

using MongoDB.Driver;
using MongoDB.Driver.Linq;

我有一个这样的对象:

public class Account
{
    public string Name { get; set; }
    public string APIKey { get; set; }
    public string Secret { get; set; }
    public bool Active { get; set; }

    public List<Store> Stores { get; set; } = new List<Store>();

    public List<User> Users { get; set; } = new List<User>();
}

商店收藏看起来像这样:

public class Store
{
    public string Name { get; set; }
    public string Location { get; set; }
    public DateTime LastMessageDate { get; set; }
    public List<Customer> Customers = new List<Customer>();
}

我想先搜索帐户,然后搜索商店,然后搜索商店对象内的客户。 我可以这样做过滤到商店级别:

var filter = Builders<Account>.Filter.Eq(e => e.ID, headers.AccountID) 
    & Builders<Account>.Filter.ElemMatch(e => e.Stores, Builders<Store>.Filter.Eq(e => e.ID, headers.StoreID))

但我不知道如何过滤到客户级别。

我试过这个:

var filter = Builders<Account>.Filter.Eq(e => e.ID, headers.AccountID) 
    & Builders<Account>.Filter.ElemMatch(e => e.Stores, Builders<Store>.Filter.Eq(e => e.ID, headers.StoreID))
    & Builders<Account>.Filter.ElemMatch(e => e.Stores.FirstOrDefault(c=>c.ID == headers.StoreID).Customers, Builders<Customer>.Filter.Eq(e => e.UUID, customerUUID));
var update = Builders<Account>.Update.Set(e => e.Stores.FirstMatchingElement().Customers, customer);

但它不起作用说:

错误 CS1660 无法将 lambda 表达式转换为类型“FieldDefinition”,因为它不是委托类型

c# mongodb .net-core mongodb-.net-driver mongodb-update
1个回答
0
投票
  1. .FirstOrDefault()
    查询中的
    filter
    将无法转换为MongoDB查询,相反,您需要使用嵌套的
    .ElemMatch()
    来通过
    UUID
    过滤客户。

  2. 要更新嵌套的 customer 元素,您需要使用 MongoDB .NET 驱动程序和

    $[<identifier>]
    中的过滤位置运算符 (
    .AllMatchingElements()
    ) 或
    arrayFilters
    方法。

var filter = Builders<Account>.Filter.Eq(e => e.ID, headers.AccountID)
    & Builders<Account>.Filter.ElemMatch(e => e.Stores, Builders<Store>.Filter.Eq(e => e.ID, headers.StoreID))
    & Builders<Account>.Filter.ElemMatch(e => e.Stores, 
        Builders<Store>.Filter.ElemMatch(e => e.Customers, Builders<Customer>.Filter.Eq(e => e.UUID, customerUUID)));
var update = Builders<Account>.Update.Set(e => e.Stores.FirstMatchingElement().Customers.AllMatchingElements("c"), customer);

var result = await _collection.UpdateOneAsync(filter, update,
    new UpdateOptions
    {
        ArrayFilters = new ArrayFilterDefinition[]
        {
            new BsonDocumentArrayFilterDefinition<Customer>
            (
                new BsonDocument("c.UUID", BsonValue.Create(customerUUID.ToString()))
            )
        }
    });
© www.soinside.com 2019 - 2024. All rights reserved.