RavenDB - 检索文档的部分内容

17

我最近在研究 Raven DB 几天了,希望将其用作我的Web聊天应用程序的存储。我有一个包含一些用户数据和聊天记录(大量聊天消息)的文档。

每次加载用户文档时,都会同时加载聊天历史记录,即使我只需要一些字段,例如用户名称、密码和电子邮件。

我的问题是:如何仅从数据库中加载文档的部分内容?


1
您的问题已由 Ayende 正确回答。将其标记为答案? - Judah Gabriel Himango
3个回答

32

Tomek,

您无法加载部分文档,但是您可以加载一个投影。

session.Query<User>()
   .Where(x=>x.Name == name)
   .Select( x=> new { x.Name, x.Email });

这将仅加载适当的字段


这将返回一个动态类型。我如何使其返回一个强类型对象,例如'UserInfo'对象? - Vegar
7
它会返回一个匿名对象,而不是动态类型。你也可以直接使用 new MyObject { Name = x.Name, Email = x.Email } 来实现。 - Ayende Rahien
var results = Session.Query<Student>().Select(s => { return new ReferencedStudent { Id = s.Id, Name = s.Name }; }); 给我报错 _无法将带有语句体的 Lambda 表达式转换为表达式树_。似乎编译器选择了错误的重载。有什么想法吗? - Vegar
好的,我明白了。去掉花括号就可以了:var results = Session.Query<Student>().Select(s => new ReferencedStudent { Id = s.Id, Name = s.Name }); - Vegar

4

根据上述“用户”场景,从我所看到的,您可以这样做:

public class UserSummary
{
    public string Name { get; set; }
    public string Email { get; set; }
}

那么你可以这样做:
documentSession.Query<User>().AsProjection<UserSummary>();

查看Raven服务器,它将以下内容作为查询的一部分输出:

?query=&pageSize=128&fetch=Name&fetch=Email&fetch=Id

看起来它只查询并返回原始对象的子集,这很好。

这也可以:

documentSession.Query<User>().Select( x=> new User { Name = x.Name, Email= x.Email })

但我认为这并不像返回一个UserSummary对象那样简洁。

对于那些已经发表过回复的人,这里有一些后续问题:

RaccoonBlog的链接举了这个例子:

https://github.com/ayende/RaccoonBlog/blob/master/RaccoonBlog.Web/Infrastructure/Indexes/PostComments_CreationDate.cs

在.AsProjection()方法之前,那种方法是更好的吗?这两种方法之间有什么区别?


似乎在RavenDB v3.5中AsProjection<>()已经不存在了,因为我在源代码中找不到它。 - Alex Klaus

2
Tomek,你不能仅加载文档的一部分。
然而,我理解你的问题。我建议为每个用户使用两个单独的文档:一个实际包含用户数据(名称、密码哈希、电子邮件等),另一个包含所有用户消息。这样,仍然可以很便宜地加载用户的所有消息,并且也可以加载用户列表以供一般用途。
这实际上与建模博客域的方式非常相似,其中有一个帖子和帖子的评论。看看RaccoonBlog,了解这是如何工作的。

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