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

Mat*_*ana 6 c# mongodb

我是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; }
}
Run Code Online (Sandbox Code Playgroud)

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

["...api/persons/1", "...api/persons/2", ...]
Run Code Online (Sandbox Code Playgroud)

有可能吗?

mne*_*syn 6

文档db中的关系是闻到的东西

一点都不.可悲的是,这个概念很受欢迎,但非关系数据库中的关系没有任何问题.这只是管理这些关系的另一种方法.

但是让我们来看看你的模型:

public ICollection<Person> Friends { get; set; }
Run Code Online (Sandbox Code Playgroud)

正如您可能已经想到的那样,这将序列化一个文档:

{ "name" : "doe",  
  "firstName" : "john", 
  "friends" : [ 
      { "name" : "rogers", 
        "firstName" : "mike", 
        "friends" : [ {"name" : "myers", "firstName" : "lucy", ... },  
        ... ] },
 ... ] }
Run Code Online (Sandbox Code Playgroud)

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

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

class Person {
    public ObjectId Id { get; set; }
    public string FirstName { get; set; }
    public List<ObjectId> FriendIds { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这将需要从您的域模型手动转换为与数据库兼容的模型,这就是您首先想要域模型的问题.

域模型的问题是它们需要RAM中的部分序列化图形.这似乎很方便从.NET方面工作,例如你可以做类似的事情

person.Friends.First().Friends.Where(p => p.Name == "Doe").Friends.Last...
Run Code Online (Sandbox Code Playgroud)

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

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

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