MongoDB引用的最佳实践

Xat*_*tep 19 c# asp.net-mvc mongodb mongodb-.net-driver

我想知道使用引用进行建模的最佳实践是什么情况.我正在使用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; }
}
Run Code Online (Sandbox Code Playgroud)

存储帖子时我只想引用所有者(用户)对象而不是整个对象底层.

目前我这样做,不知道更好的方式......

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

..

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

userRepository和postRepository属于MongoRepository类型.

这是使用带有C#/ MVC(4)的MongoDB解决我的问题的正确方法吗?

小智 24

您可以使用DBRef对象而不是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; }
}    
Run Code Online (Sandbox Code Playgroud)

然后你可以:

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

  • 它已重命名为MongoDBRef (2认同)

Rik*_*igh 11

Mongo是一个文档数据库,如果你习惯使用sql server,它需要一种略微不同的思维方式.

由于您不希望在每个帖子中都有用户密码详细信息,我可能会这样做的方法是创建一个新类来包含显示帖子可能需要的任何用户信息.

public class PostOwnerInfo
{
    public string UserId { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

更新post实体,将Owner属性替换为PostOwnerInfo类型的OwnerInfo属性.

然后,当您创建新帖子时,请执行以下操作.

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

这样,当您查询帖子时,它将具有您在其所有者信息属性中显示帖子所需的所有用户信息,而无需进一步查询.

var post = postRepository.GetById(previouslySavedPostId);
// post.OwnerInfo will contain user info
Run Code Online (Sandbox Code Playgroud)

有一定数量的数据冗余,但在文档数据库中,我就是这样做的.

如果您出于任何原因需要完整的用户信息,只需像以前一样对其进行单独查询.

这个想法是您将帖子所需的所有用户信息存储在帖子的子文档中,因此您不需要为用户进行单独的查询.

如果用户数据发生变化,只需更新用户发出的所有帖子上的UserInfo字段即可.

您的用户数据很少会更改,但您会经常查询帖子.

  • 这是我试图通过引用来避免的。如果我更改用户,那么它将与帖子中的用户不同。将用户存储在 Post 中会很糟糕,因为它包含用户名、密码等。需要一个聪明的“睁眼”方法...... (2认同)