MongoDB最佳实践:关于引用的使用建议

25
我想知道在下面的情况下使用引用进行建模的最佳实践是什么。我正在使用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; }
}

在存储Post时,我只想引用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类型。

这是否是使用C#/MVC(4)与MongoDB解决问题的正确方法?


请查看MongoDB.Entities。这个库使得引用/关系相当容易和直接。它支持各种实体之间的关系,例如:一对一,一对多和多对多。 - Dĵ ΝιΓΞΗΛψΚ
2个回答

29

您可以使用MongoDBRef对象代替用户对象。

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

1
DBRef和FollowReference不存在。 - iYonatan
3
已经更名为MongoDBRef。 - nuhusky2003
1
这个解决方案现在还有用吗? - Akmal Salikhov

13

Mongo是一个文档型数据库,如果你习惯使用SQL Server,它需要略微不同的思维方式。

由于您不希望在每篇文章中都包含用户密码详细信息,我可能会创建一个新类来包含任何可能需要显示帖子的用户信息。

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

更新您的文章实体,将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);

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

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

在文档数据库中,有一定数量的数据冗余,但这是我的处理方法。

如果您需要完整的用户信息,请像以前一样单独查询。

思路是在帖子的子文档中存储所需的所有用户信息,因此您不需要为用户执行单独的查询。

如果用户数据发生更改,请更新用户发布的所有帖子的UserInfo字段。

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


3
这就是我通过引用所尝试避免的。如果我更改用户,那么它将与帖子中的用户不同。在帖子中存储用户会很糟糕,因为其中包含用户名、密码等信息。需要一种聪明的“开创性”方法... - Xatep
是的,你说得对。我真的不想在每篇文章中存储密码数据。我已经更新了我的回答。 - Rik Leigh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接