Передовая практика MongoDB для ссылок - программирование
Подтвердить что ты не робот

Передовая практика MongoDB для ссылок

Мне интересно, какая лучшая практика для моделирования, используя ссылки, будет иметь такую ​​ситуацию. Я использую MongoRepository библиотеку.

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; }
}

При сохранении сообщения я хочу ссылаться только на объект Owner (User) вместо всего основного объекта.

В настоящее время я делаю это так, не зная лучшего способа...

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 и postRepository имеют тип MongoRepository.

Это правильный подход к решению моей проблемы с использованием MongoDB с помощью С#/MVC (4)?

4b9b3361

Ответ 1

Вы можете использовать объект MongoDBRef вместо объекта User.

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; }
}    

Тогда ты можешь:

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);

Ответ 2

Mongo - это база данных документов, и если вы привыкли использовать SQL-сервер, это требует немного другого способа мышления.

Поскольку вам не нужны данные пароля пользователя в каждом отдельном сообщении, я бы, вероятно, сделал это, чтобы создать новый класс, содержащий любую информацию о пользователе, которая может потребоваться для отображения сообщения.

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

Обновите свой почтовый объект, заменив свойство Owner свойством OwnerInfo, типа PostOwnerInfo.

Затем, когда вы создаете новое сообщение, сделайте следующее.

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);

Таким образом, когда вы запрашиваете сообщение, у него будет вся информация о пользователе, которую вам требуется, чтобы отобразить сообщение в нем свойство OwnerInfo без дальнейших запросов.

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

Существует определенное количество избыточности данных, но в базе данных документа это то, как я это сделал.

Если вам нужна полная информация о пользователе по какой-либо причине, просто выполните отдельный запрос для него, как вы делали раньше.

Идея заключается в том, что вы сохраняете всю информацию о пользователе, которая вам нужна для публикации в дочернем документе сообщения, поэтому вам не нужно делать отдельный запрос для пользователя.

Если пользовательские данные обходятся, просто обновите поле UserInfo во всех сообщениях, сделанных вашим пользователем.

Ваши пользовательские данные редко меняются, но вы часто будете запрашивать сообщения.