使用 mongodb C# 驱动程序删除并返回嵌套数组中的文档

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

我在使用官方 mongodb c# 驱动程序删除数组中的文档时遇到问题。我想做的也是返回已删除的文档。

这是我的班级的样子:

public class Holder
{
    public string Owner { get; set; }
    public List<Card> Cards { get; set; }
}

public class Card
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Placement { get; set; }
}

这是文档的摘录:

{
  "owner": "656dd33e0300"
  "cards" : [
    {
      "id": "s39CNzu4Na3",
      "name" : "Department",
      "placement" : "8a"
    },
    ...
  ]
}

我的第一个想法是获取该卡,然后使用以下命令将其删除:

var filter = Builders<Card>.Filter.Eq(x => x.Id, cardId);

var res = await collection.DeleteOneAsync(
     Builders<Holder>.Filter.Eq(e => e.Owner, owner) &
     Builders<Holder>.Filter.ElemMatch(e => e.Cards, filter)
    );
try {            
    return res.DeletedCount > 0;
}
catch (Exception ex) {
    throw;
}

但这最终只是删除了列表中的所有卡片。 我一直在尝试使用

FindOneAndDeleteAsync
但我无法让它工作。

c# mongodb document mongodb-.net-driver
1个回答
0
投票

从您的代码中,您将删除整个

Holder
文档,但不会从
Card
文档中的
Cards
数组中删除
Holder
元素。

我认为 MongoDB .NET 驱动程序不支持删除和返回已删除元素(API)。因此,您应该:

  1. 过滤文档并获取过滤后的

    Card
    元素。

  2. Pull
    Card
    数组中匹配的
    Cards
    元素。

  3. 返回

    res.ModifiedCount > 0
    表示卡片元素被移除,物品被移除。

var filter = Builders<Card>.Filter.Eq(x => x.Id, cardId);

var holder = await collection.Find(
        Builders<Holder>.Filter.Eq(e => e.Owner, owner) &
        Builders<Holder>.Filter.ElemMatch(e => e.Cards, filter))
    .Project<Holder>(Builders<Holder>.Projection
        .Include(x => x.Owner)
        .ElemMatch(x => x.Cards, filter))
    .FirstOrDefaultAsync();

if (holder == null || !holder.Cards.Any())
{
    return new
    {
        IsCardDeleted = false,
        DeletedCards = (List<Card>)null
    };
}

UpdateResult res = await collection.UpdateOneAsync(
     Builders<Holder>.Filter.Eq(e => e.Owner, owner) &
     Builders<Holder>.Filter.ElemMatch(e => e.Cards, filter),
     Builders<Holder>.Update.PullFilter(e => e.Cards, filter)
);

if (res.ModifiedCount == 0)
{
    return new
    {
        IsCardDeleted = false,
        DeletedCards = (List<Card>)null
    };
}

return new
{
    IsCardDeleted = true,
    DeletedCards = holder.Cards
};

© www.soinside.com 2019 - 2024. All rights reserved.