当前位置: 首页 > news >正文

克服 MongoDB C# 驱动程序的局限性

mongodb 驱动程序有其局限性,有时您需要手动或使用查询编辑器/编写器编写高级查询。为了能够运行这些查询并从 C# 代码中注入值,您需要编写BsonDocuments或执行字符串连接,这会导致丑陋、不可读、充满魔法字符串的令人憎恶的结果。

为了解决这个问题,并将您的 C# 实体模式与原始查询结合起来,库MongoDB.Entities提供了一个基于标签替换的模板系统。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

以以下查找查询为例:

db.Book.find(
  {
    Title : 'book_name',
    Price : book_price
  }
)

要将此文本查询与您的 C# 模型耦合并传入标题和价格的值,只需将您想要替换的部分括起来<>然后将它们转换为替换标签/标记,如下所示:

db.Book.find(
  {
    <Title> : '<book_name>',
    <Price> : <book_price>
  }
)

模板系统基于一个名为的特殊类Template。您只需实例化一个“模板”对象,将标记的文本查询提供给构造函数。然后,您在模板对象上链接方法调用来替换您在查询上标记的每个标签,如下所示:

var query = new Template<Book>(@"
{
  <Title> : '<book_name>',
  <Price> : <book_price>
}")
.Path(b => b.Title)    
.Path(b => b.Price)
.Tag("book_name","The Power Of Now")
.Tag("book_price","10.95");

var result = await DB.Find<Book>()
                     .Match(query)
                     .ExecuteAsync();

发送给 mongodb 的结果查询如下:

db.Book.find(
  {
    Title : 'The Power Of Now',
    Price : 10.95
  }
)

该方法只是用提供的值替换文本查询中匹配的标签。使用该方法时.Tag()不必使用<和字符。事实上,避免使用它,因为如果使用它们,标签将不匹配。>.Tag()

.Path()方法是该类提供的众多方法之一,您可以使用它通过提供 lambda/成员表达式来获取属性的完整“点状”路径。请参阅此处的Prop“Prop”类的文档,了解其他可用方法。

请注意,大多数这些“Prop”方法只需要一个参数。您向它们提供的任何成员表达式都会转换为这样的属性/字段路径:

表达式:x => x.Authors[0].Books[0].Title

结果路径:Authors.Books.Title

如果您的文本查询有标签,<Authors.Books.Title>它将被“Prop”类方法的结果路径替换。

当发生以下3种情况时,模板系统将会抛出异常。

  1. 输入的查询/文本没有使用<>字符标记的标签。
  2. 输入查询包含您忘记指定替换的标签。
  3. 您指定的替换项在查询中没有匹配的标签。

这种运行时错误比由于查询没有产生任何结果或产生错误结果而导致代码默默失败要好。

一些例子:

聚合管道:

var pipeline = new Template<Book>(@"
[
    {
      $match: { <Title>: '<book_name>' }
    },
    {
      $sort: { <Price>: 1 }
    },
    {
      $group: {
        _id: '$<AuthorId>',
        product: { $first: '$$ROOT' }
      }
    },
    {
      $replaceWith: '$product'
    }
]")
.Path(b => b.Title)
.Path(b => b.Price)
.Path(b => b.AuthorId)
.Tag("book_name", "MongoDB Templates");

var book = await DB.PipelineSingleAsync(pipeline);

使用匹配表达式查找:

var query = new Template<Author>(@"
{
  $and: [
    { $gt: [ '$<Age>', <author_age> ] },
    { $eq: [ '$<Surname>', '<author_surname>' ] }
  ]
}")
.Path(a => a.Age)
.Path(a => a.Surname)
.Tag("author_age", "54")
.Tag("author_surname", "Tolle");

var authors = await DB.Find<Author>()
                      .MatchExpression(query)
                      .ExecuteAsync();

使用聚合管道阶段进行更新:

var pipeline = new Template<Author>(@"
[
  { $set: { <FullName>: { $concat: ['$<Name>',' ','$<Surname>'] } } },
  { $unset: '<Age>'}
]")             
.Path(a => a.FullName)
.Path(a => a.Name)
.Path(a => a.Surname)
.Path(a => a.Age);

await DB.Update<Author>()
        .Match(a => a.ID == "xxxxx")
        .WithPipeline(pipeline)
        .ExecutePipelineAsync();

使用数组过滤器进行更新:

var filters = new Template<Author>(@"
[
  { '<a.Age>': { $gte: <age> } },
  { '<b.Name>': 'Echkart Tolle' }
]")
.Elements(0, author => author.Age)
.Elements(1, author => author.Name);
.Tag("age", "55")        

var update = new Template<Book>(@"
{ $set: { 
    '<Authors.$[a].Age>': <age>,
    '<Authors.$[b].Name>': '<name>'
  } 
}")
.PosFiltered(book => book.Authors[0].Age)
.PosFiltered(book => book.Authors[1].Name)
.Tag("age", "55")
.Tag("name", "Updated Name");

await DB.Update<Book>()
        .Match(book => book.ID == "xxxxxxxx")
        .WithArrayFilters(filters)
        .Modify(update)
        .ExecuteAsync();

后续步骤...

希望上述文本查询模板系统能够激发您的兴趣,让您更深入地学习如何使用 C# 来使用 MongoDB。该软件包MongoDB.Entities让您能够非常轻松地与 MongoDB 服务器通信。其 API 的各个方面均已在官方网站上记录。您也可以在 GitHub 上查看源代码:https://github.com/dj-nitehawk/MongoDB.Entities

参考文章:Overcoming The Limitations Of MongoDB C# Driver - DEV Community

Welcome | MongoDB.Entities

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。


文章转载自:

http://mUTCLo7M.wqmyh.cn
http://B7wCaj8t.wqmyh.cn
http://g2t5gGDp.wqmyh.cn
http://SG81RyWD.wqmyh.cn
http://AlOstVj4.wqmyh.cn
http://8yj7afIr.wqmyh.cn
http://t1Yd1E86.wqmyh.cn
http://5AaThLYe.wqmyh.cn
http://jayALKG3.wqmyh.cn
http://fyAHONOh.wqmyh.cn
http://QqlN9Kjv.wqmyh.cn
http://dhh7mpCV.wqmyh.cn
http://chG2W0qV.wqmyh.cn
http://7g0TXMQl.wqmyh.cn
http://dlcN4DIn.wqmyh.cn
http://fHVm6sfP.wqmyh.cn
http://mEOI1ig3.wqmyh.cn
http://nIMd6AMu.wqmyh.cn
http://cwvYFeB6.wqmyh.cn
http://V4dqwQAl.wqmyh.cn
http://YlsrGvNJ.wqmyh.cn
http://bhE4hHFM.wqmyh.cn
http://X0UnlDSk.wqmyh.cn
http://8SMFCJzR.wqmyh.cn
http://5YG5I1IY.wqmyh.cn
http://UGnIKPbO.wqmyh.cn
http://lyl9Z4QG.wqmyh.cn
http://qrmI8jkq.wqmyh.cn
http://JIls600Z.wqmyh.cn
http://TIZZtMFC.wqmyh.cn
http://www.dtcms.com/a/382490.html

相关文章:

  • 详解MySQL JSON字段索引设置方案
  • 从基础到实践(四十五):车载显示屏LCD、OLED、Mini-LED、MicroLED的工作原理、设计差异等说明
  • 汽车座椅固定装置及头枕强度动静态试验系统
  • 机器学习-过拟合和欠拟合
  • win11business和consumer版本有什么区别
  • 一个支持多平台的 AI 客户端
  • 浏览器调试工具详解
  • <测量透明液体折射率的深度学习方法>论文总结
  • 下载 MNIST 数据集方法 mnist_train.csv 和 mnist_test.csv
  • 【完整源码+数据集+部署教程】足球场景分割系统: yolov8-seg-C2f-EMBC
  • 算法 --- 链表
  • 技术演进中的开发沉思-99 Linux服务编程系列:程序员视角下的 TCP/IP 通信案例
  • 面试(二)
  • 计算机技术在国有企业档案信息化建设的应用
  • 2025.9.11英语红宝书【必背1-5】
  • Python核心语法篇【1】:环境安装配置与第一个“Hello World”程序
  • 【C++练习】18.C++求两个整数的最小公倍数(LCM)
  • yolo识别手势释放忍术
  • Amass 被动与主动子域收集
  • 【左程云算法08】栈和队列相互实现
  • RocketMQ详解,消息队列实战
  • 4.6 我国股票的类型(43)
  • ​​抢占储能新高地:汇川DSP驱动软件开发范式变革与人才重塑​
  • tree 遍历目录
  • 不邻排列:如何优雅地避开“数字CP“
  • Vue3应用执行流程详解
  • css 高度从 0 到 auto 的动画效果 `interpolate-size: allow-keywords`
  • 8-获取文件和目录信息
  • SPAR类比推理模型学习(与常见小目标检测方法总结)
  • 提示工程架构师分享:如何用提示词升级职业教育的实操案例教学?(万字长文来袭,高能预警!!!)