【发布时间】:2011-10-19 23:19:30
【问题描述】:
我玩了几天 Raven DB,我想将它用作我的网络聊天应用程序的存储。我有一个包含一些用户数据和聊天记录的文档 - 这是大集合聊天消息。
每次我加载用户文档时,聊天记录也会被加载,即使我只需要几个字段,例如:用户名、密码和电子邮件。
我的问题是:如何从数据库中只加载部分文档?
【问题讨论】:
-
Ayende 正确回答了您的问题。将其标记为答案?
标签: ravendb
我玩了几天 Raven DB,我想将它用作我的网络聊天应用程序的存储。我有一个包含一些用户数据和聊天记录的文档 - 这是大集合聊天消息。
每次我加载用户文档时,聊天记录也会被加载,即使我只需要几个字段,例如:用户名、密码和电子邮件。
我的问题是:如何从数据库中只加载部分文档?
【问题讨论】:
标签: ravendb
托梅克,
您无法加载部分文档,但您可以加载投影。
session.Query<User>()
.Where(x=>x.Name == name)
.Select( x=> new { x.Name, x.Email });
这将只加载适当的字段
【讨论】:
var results = Session.Query<Student>().Select(s => { return new ReferencedStudent { Id = s.Id, Name = s.Name }; }); 给我错误带有语句体的 lambda 表达式无法转换为表达式树。似乎编译器选择了错误的重载。有什么想法吗?
var results = Session.Query<Student>().Select(s => new ReferencedStudent { Id = s.Id, Name = s.Name });
据我所知,您可以这样做(基于上面的原始“用户”场景):
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 的链接有这个例子:
该方法是否优于 .AsProjection()?这两种方法有什么区别?
【讨论】:
AsProjection<>() 在 RavenDB v3.5 中不再存在,因为我在 source code 中找不到它。
Tomek,您不能只加载文档的一部分。
但是,我理解您的问题。我建议为每个用户使用两个单独的文档:一个实际包含用户数据(姓名、密码哈希、电子邮件等),另一个包含 所有 用户消息。这样一来,加载用户的所有消息以及加载用户列表用于一般用途仍然非常便宜。
这实际上与对博客域建模的方式非常相似,其中您有一个帖子和帖子 cmets。看看RaccoonBlog 看看它是如何工作的。
【讨论】: