25

I'm wondering what the best practice for modelling by using references would be given situation under. I'm using MongoRepository library.

public class User : Entity
{
   publis string Id { get; set; }
   public string Email { get; set; }
   public string Password { get; set; }
}

public class Post : Entity
{
   public string Id { get; set; }
   public string Title { get; set; }
   public string Summary { get; set; }
   public DateTime Added { get; set; }
   public User Owner { get; set; }
}

When storing the Post I want only reference to Owner (User) object instead of whole object underlying.

Currently I'm doing it like this, not knowing of better way...

var post = new Post
{
   Title = "Example title",
   Summary = "asd asd",
   Added = DateTime.Now,
   Owner = new User { Id = "someExistingUserId" }
};
postRepository.Update(post); //Save

..

//Then to get the post
var post = postRepository.GetById("previouslySavedPostId");
post.Owner = userRepository.GetById(post.Owner.Id);
return post;

userRepository and postRepository are of MongoRepository type.

Is this the correct approach to solving my problem using MongoDB with C#/MVC(4)?

Xatep
  • 353
  • 1
  • 5
  • 11
  • have a look at [MongoDB.Entities](https://github.com/dj-nitehawk/MongoDB.Entities). references/ relationships are quite easy and straightforward with this library. it supports all kinds of relationships between entities like: one-to-one, one-to-many and many-to-many – Dĵ ΝιΓΞΗΛψΚ May 24 '19 at 06:07

2 Answers2

29

You can use MongoDBRef object instead of User object.

public class Post : Entity
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string Summary { get; set; }
    public DateTime Added { get; set; }
    public MongoDBRef Owner { get; set; }
}    

Then you can:

var mongo = new Mongo(config.BuildConfiguration());
mongo.Connect();        
var DB = mongo.GetDatabase(_dataBaseName)

var post = new Post();
post.Owner = new MongoDBRef("User", userId); // First parameter is a mongoDB collection name and second is object id
// To fetch object referenced by DBRef you should do following
var owner = DB.FollowReference<User>(post.Owner);
FalcoGer
  • 2,278
  • 1
  • 12
  • 34
Jasmin Gacic
  • 314
  • 2
  • 3
13

Mongo is a document database and if you are used to using sql server it requires a slightly different way of thinking.

As you don't want the user password details in every single post, the way i would probably do it is to create a new class to contain any user info that might be required to display a post.

public class PostOwnerInfo
{
    public string UserId { get; set; }
    public string Name { get; set; }
}

Update your post entity, replacing the Owner property with an OwnerInfo property, of type PostOwnerInfo.

Then when you create a new post, do the following.

var user = userRepository.GetById(someExistingUserId);

var post = new Post
{
   Title = "Example title",
   Summary = "Example summary",
   Added = DateTime.Now,
   OwnerInfo = new PostOwnerInfo
   {
        UserId = user.Id,
        Name = user.Name
   }
};

postRepository.Update(post);

This way when you query for a post it will have all the user info that you require to display the post in it's OwnerInfo property with no further queries required.

var post = postRepository.GetById(previouslySavedPostId);
// post.OwnerInfo will contain user info

There is a certain amount of data redundancy, but in an document database this is how i would do it.

If you need the full user info for any reason just do a seperate query for it as you were doing before.

The idea is that you store all the user info you need for a post in a child document of the post, so you shouldn't need to do a seperate query for the user.

If the user data chages, just update the UserInfo field on all posts made by your user.

Your user data will rarely change, but you will query for posts very often.

Rik Leigh
  • 1,318
  • 1
  • 7
  • 7
  • 3
    This is what I try to avoid by referencing. If I change the User, then it will be different from the User in the Post. It would be bad to store User in Post as it contains username, password, etc. Need a smart "eye opening" approach... – Xatep Feb 14 '13 at 22:48
  • Yes you are correct. Wouldn't really want to store password data with each post. Updated my answer – Rik Leigh Feb 15 '13 at 00:15