MongoDB C#实体映射:;一对多关系”;

本文关键字:一对多 关系 实体 映射 MongoDB | 更新日期: 2024-10-19 23:40:01

我是MongoDb的新手,但我知道在文档数据库中谈论关系是有味道的。不管怎样,我只是想了解它是否符合我的需求,以及它的局限性在哪里。

我的域中只有一个简单的c#实体,它是:

class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public ICollection<Person> Friends { get; set; }
}

我只希望序列化过程使该集合成为的列表

["...api/persons/1", "...api/persons/2", ...]

在某种程度上可能吗?

MongoDB C#实体映射:;一对多关系”;

文档数据库中的关系闻起来像

不,一点也不。遗憾的是,这个概念很流行,但非关系数据库中的关系并没有错。这只是管理这些关系的一种不同方法。

但让我们看看你的模型:

public ICollection<Person> Friends { get; set; }

正如您可能已经发现的那样,这将序列化文档的

{ "name" : "doe",  
  "firstName" : "john", 
  "friends" : [ 
      { "name" : "rogers", 
        "firstName" : "mike", 
        "friends" : [ {"name" : "myers", "firstName" : "lucy", ... },  
        ... ] },
 ... ] }

换句话说,这些不会序列化为关系,而是作为嵌入文档

现在,如果你想要关系,最简单、最干净的方法就是存储关系:

class Person {
    public ObjectId Id { get; set; }
    public string FirstName { get; set; }
    public List<ObjectId> FriendIds { get; set; }
}

这将需要手动从域模型转换为与数据库兼容的模型,这就引出了为什么首先需要域模型的问题。

域模型的问题在于,它们需要RAM中的部分序列化图。从.NET端使用它似乎很方便,例如,你可以做一些类似的事情

person.Friends.First().Friends.Where(p => p.Name == "Doe").Friends.Last...

但目前还不清楚如何从数据库中获取所有这些,因为这个简单的单行表达式可能需要至少4次往返数据库。虽然可以实现这样的映射(透明激活),但它向程序员隐藏了许多重要信息。

如果你在等式中添加修改(和修改跟踪),事情会很快变得非常混乱。

此外,这个模型对我来说就像一个m:n关系(一个人可以有很多朋友,一个人可以被很多其他人称为朋友,对吧?)。对于m:n关系,嵌入引用列表可能不是最好的方法,但也有其他选择。