我在使用官方的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; }
}

以下是该文件的一个exerpt:

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

我的第一个 idea 就是拿到卡片,然后用以下命令删除它:

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,但就是不能用.

Update 首先,非常感谢@markus和@yongshun,因为他们的答案都对我有用,我 Select @markus作为答案,因为它是第一个有效的答案,我喜欢更短的代码,与我的其他代码类似.

推荐答案

据我所知,您不想删除根文档,而是从数组中删除子文档.可以使用UPDATE-语句(DELETE用于将根文档作为一个整体删除)来完成此操作.

为了使其起作用,您需要创建一个筛选器来查找文档,然后在文档上运行一个带有PullFilter的更新.

此外,您还希望返回在更新过程中删除的子文档.没有返回子文档的语句,但可以使用FindOneAndUpdateAsync返回子文档被删除前的状态:

var arrayFilter = Builders<Card>.Filter.Eq(x => x.Id, cardId);
// Find a document with a matching owner that contains at least one card with the specified id
var docFilter = Builders<Holder>.Filter.Eq(e => e.Owner, owner) 
    & Builders<Holder>.Filter.ElemMatch(e => e.Cards, arrayFilter);
// Remove all cards from the array that have a matching id 
// (id should be unique so only one card should be removed)
var update = Builders<Holder>.Update.PullFilter(e => e.Cards, arrayFilter);
// Find the document and return it in the state before the update
var before = await coll.FindOneAndUpdateAsync(
    docFilter,
    update,
    new FindOneAndUpdateOptions<Holder, Holder>() { ReturnDocument = ReturnDocument.Before });
// Get removed card from the returned document
var removedCard = before.Cards.SingleOrDefault(x => x.Id == cardId);

Csharp相关问答推荐

C#将参数传递给具有变化引用的变量

EF Core Fluent API中定义的多对多关系

C#中使用BouncyCastle计算CMac

如何使用while循环实现异常处理

为什么总输出就像12.3没有一分一样?

选取器与.NET Maui MVVM的绑定属性

MongoDB.NET-将数据绑定到模型类,但无法读取整数值

如何在页面重新加载后保持菜单切换状态

为什么Regex.IsMatch(";\\t";,";\\t";)返回FALSE而不是TRUE?

我如何让我的秒表保持运行场景而不重置

如何在VS代码中为C#DotNet配置.json选项以调试内部终端的控制台应用程序

在.NET 8最低API中从表单绑定中排除属性

为什么@rendermode Interactive Auto不能在.NET 8.0 Blazor中运行?

是否可以在Entity Framework Core中使用只读 struct 作为拥有实体?

多个选项卡上的MudForm验证

我应该为C#12中的主构造函数参数创建私有属性吗?

在构造函数中传递C#函数以用作EventHandler委托的订阅服务器

在ObservableCollection上使用[NotifyPropertyChangedFor()]源代码生成器不会更新UI

在Visual Studio 2022中查找Xamarin模板时遇到问题

Windows 10上埃及标准时间的时区偏移不正确