Reputation: 73
I'm new to MongoDb, but i am aware that speaking about relation in a document db is something that smell. Anyway i'm trying it just to understand if it fits my needs and where are its limits.
I've just a simple c# entity in my domain that is:
class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public ICollection<Person> Friends { get; set; }
}
And i just want that the serialization process makes that collection a sort of list of
["...api/persons/1", "...api/persons/2", ...]
is it possible in some way?
Upvotes: 7
Views: 12544
Reputation: 46291
relation in a document db is something that smell
No, not at all. Sadly, that notion is popular, but there's nothing wrong with relations in non-relational databases. It's just a different approach to manage those relations.
But let's look at your model:
public ICollection<Person> Friends { get; set; }
As you have probably figured out, that would serialize a tree of documents:
{ "name" : "doe",
"firstName" : "john",
"friends" : [
{ "name" : "rogers",
"firstName" : "mike",
"friends" : [ {"name" : "myers", "firstName" : "lucy", ... },
... ] },
... ] }
In other words, these would not serialize as relations, but as embedded documents.
Now the easiest and cleanest approach is to store relations if you want relations:
class Person {
public ObjectId Id { get; set; }
public string FirstName { get; set; }
public List<ObjectId> FriendIds { get; set; }
}
That will require manually translating from your domain model to a database-compatible model, which begs the question why you want a domain model in the first place.
The problem with domain models is that they require a partially serialized graph in RAM. That seems convenient to work with from the .NET side, e.g. you could do something like
person.Friends.First().Friends.Where(p => p.Name == "Doe").Friends.Last...
But it's utterly unclear how to fetch all this from the database, because that simple one-line expression would probably require at least 4 round-trips to the database. While such a mapping can be implemented (transparent activation), it hides a lot important information from the programmer.
If you add modifications (and modification tracking) to the equation, things get very messy very quickly.
Also, the model looks like an m:n relation to me (a person can have many friends, and a person could be referenced as friends by many other persons, right?). For m:n relations, embedding lists of references might not be the best approach, but there are alternatives.
Upvotes: 14