c# – 如何处理像Mongo这样的文档数据库中单独存储的对象的引用?

c# – 如何处理像Mongo这样的文档数据库中单独存储的对象的引用?,第1张

概述这个问题很容易在像Entity Framework或NHibernate这样的ORM中解决,但我没有在MongoDb的c#驱动程序中看到任何现成的解决方案.假设我有A类型的对象集合引用对象类型B,我需要将它存储在单独的集合中,这样一旦特定对象B被更改,所有引用它的A都需要知道更改.换句话说,我需要对象关系进行规范化.同时我需要在类中引用A,而不是由Id引用,而是通过类型引用,如下所示: publi 这个问题很容易在像Entity Framework或NHibernate这样的ORM中解决,但我没有在MongoDb的c#驱动程序中看到任何现成的解决方案.假设我有A类型的对象集合引用对象类型B,我需要将它存储在单独的集合中,这样一旦特定对象B被更改,所有引用它的A都需要知道更改.换句话说,我需要对象关系进行规范化.同时我需要在类中引用A,而不是由ID引用,而是通过类型引用,如下所示:
public class A{   public B RefB { get; set; }}

我是否必须自己处理所有这些引用一致性?如果是这样,哪种方法最好用?我是否必须在班级中同时保留B的ID和B引用,并以某种方式处理同步它们的值:

public class A{    // Need to implement reference consistency as well    public int RefBID { get; set; }    private B _refB;    [BsonIgnore]    public B RefB    {        get { return _refB; }        set { _refB = value; RefBID = _refB.ID }    }}

我知道有人可能会说关系数据库遇到这种情况最好,我知道,但我真的必须使用像MongoDb这样的文档Db,它解决了很多问题,而且在大多数情况下我需要为我的项目存储非规范化的对象,但有时我们可能会在单个存储中需要混合设计.

解决方法 这主要是一个建筑问题,它可能取决于个人品味.我将尝试检查利弊(实际上只是缺点,这是相当自以为是):

在数据库级别,MongoDB没有提供强制参照完整性的工具,所以是的,你必须自己做.我建议你使用如下所示的数据库对象:

public class DBObject {    public ObjectID ID {get;set;}}public class Department : DBObject {  // ...}public class EmployeeDB : DBObject{    public ObjectID DepartmentID {get;set;}}

无论如何,我建议在数据库级别使用这样的普通DTO.如果你想要额外的糖,把它放在一个单独的层,即使这意味着一点点复制. DB对象中的逻辑需要非常好地理解驱动程序对对象进行水合的方式,并且可能需要依赖于实现细节.

现在,您是否想要使用更“智能”的对象是一个优先事项.实际上,许多人喜欢使用强类型的自动激活访问器,例如,

public class Employee{    public Department     { get { return /* the department object,magically,from the DB */ } }}

这种模式带来了许多挑战:

>它需要Employee类(模型类)才能从数据库中保存对象.这很棘手,因为它需要注入数据库,或者您需要一个静态对象来进行数据库访问,这也很棘手.
>访问部门看起来非常便宜,但事实上,它会触发数据库 *** 作,它可能很慢,可能会失败.这完全是来自呼叫者的隐藏.
>在1:n关系中,事情变得更加复杂.例如,部门是否还会公开雇员名单?如果是这样,那真的是一个列表(即一旦你开始阅读第一个,所有员工必须被反序列化吗?)或者它是一个懒惰的MongoCursor?
>更糟糕的是,通常不清楚应该使用什么样的缓存.假设你得到myDepartment.Employee [0] .Department.name.显然,这段代码并不聪明,但想象一下,调用堆栈中有一些专门的方法.他们可能会像这样调用代码,即使它更隐藏.现在,一个天真的实现实际上会再次反序列化ref’d部门.那很难看.另一方面,积极缓存是危险的,因为您可能实际上想要重新获取对象.
>最糟糕的是:更新.到目前为止,挑战基本上是只读的.现在让我说我呼叫employeeJohn.Department.name =’PixelPushers’和employeeJohn.Save().这会更新部门吗?如果是这样,john的更改是先序列化还是在依赖对象更改后?版本控制和锁定怎么样?
>许多语义很难实现:employeJohn.Department.Employees.Clear()可能很棘手.

许多ORM使用一组复杂的模式来允许这些 *** 作,因此这些问题并非无法解决.但是ORM通常在100k到超过1M行代码(!)的范围内,我怀疑你有这样的时间.在RDBMS中,需要激活相关对象并使用某事物.像ORM更严重,因为你不能嵌入例如发票中的行项目列表,因此必须使用连接表示每个1:n或m:n关系.这称为对象关系不匹配.

据我所知,文档数据库的概念是,您不需要像在RDBMS中那样不自然地破坏模型.不过,还有“对象边界”.如果您将数据模型视为连接节点的网络,那么挑战在于了解您当前正在使用的数据部分.

就个人而言,我更喜欢不在其上放置抽象层,因为抽象是漏洞,它隐藏了来自调用者的真实情况,并试图用相同的锤子解决每个问题.

Nosql的部分想法是,您的查询模式必须与数据模型仔细匹配,因为您不能简单地将JOIN锤应用于任何可见的表.

所以,我的意见是:坚持使用薄层并在服务层执行大部分数据库 *** 作.移动DTO而不是设计一个复杂的域模型,只要您需要添加锁定,mvcc,级联更新等,它就会分开.

总结

以上是内存溢出为你收集整理的c# – 如何处理像Mongo这样的文档数据库中单独存储的对象的引用?全部内容,希望文章能够帮你解决c# – 如何处理像Mongo这样的文档数据库中单独存储的对象的引用?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1263492.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存