使用Gremlin.NET查询Gremlin:如何返回带深度遍历的强类型类
解决方案
核心问题分析
在强类型Project.To<T>()的By方法中,第一个lambda参数对应的是DTO对象(如conversation => ...中的conversation是ConversationDto实例),而非Gremlin的顶点查询对象,因此没有OutE()这类图查询方法。正确的做法是利用By方法的重载,在第二个lambda参数中操作Gremlin查询对象来获取关联数据,再映射到DTO属性。
修改后的强类型代码
IVertexGremlinQuery<ConversationDto> conversationWithMessages = paginatedConversations .Project(p => p.To<ConversationDto>() // 简单属性映射,保持原有逻辑 .By(dto => dto.Id, g => g.Values(c => c.Id)) .By(dto => dto.Title, g => g.Values(c => c.Title)) .By(dto => dto.IsDirectMessage, g => g.Values(c => c.IsDirectMessage)) // 关联属性:第二个lambda参数g是Gremlin顶点查询对象,可调用OutE等方法 .By((dto, g) => g.OutE<BelongsTo>().InV<Account>() .Project(account => account.To<AccountDto>() .By(aDto => aDto.Id, aG => aG.Values(a => a.Id)) .By(aDto => aDto.Email, aG => aG.Values(a => a.Email)) .By(aDto => aDto.FullName, aG => aG.Values(a => a.FullName)) .By(aDto => aDto.Gender, aG => aG.Values(a => a.Gender)) ).Fold(), (dto, participants) => dto.Participants = participants) // 消息关联同理 .By((dto, g) => g.OutE<Has>().InV<ConversationMessage>() .Project(message => message.To<ConversationMessageDto>() .By(mDto => mDto.Id, mG => mG.Values(m => m.Id)) .By(mDto => mDto.Content, mG => mG.Values(m => m.Content)) .By(mDto => mDto.SenderId, mG => mG.Values(m => m.SenderId)) .By(mDto => mDto.Timestamp, mG => mG.Values(m => m.Timestamp)) ).Fold(), (dto, messages) => dto.Messages = messages) ); var source = await conversationWithMessages.ToArrayAsync(); return source;
代码说明
- 简单属性映射:对于DTO的基础属性(Id、Title等),第一个lambda参数指向DTO的属性,第二个参数用
g.Values()获取顶点的对应属性值。 - 关联属性映射:使用
By((dto, g) => ..., (dto, result) => ...)的重载:- 第一个lambda的
g是Gremlin的顶点查询对象,可正常调用OutE()、InV()等图查询方法,获取关联节点数据并投影为对应的DTO集合。 - 第二个lambda将查询结果赋值给DTO的对应属性(如
dto.Participants = participants)。
- 第一个lambda的
修改后即可正常获取强类型的ConversationDto集合,输出结构与ToDynamic()的结果完全一致。
内容的提问来源于stack exchange,提问作者Zhylaw
相关产品推荐
相关产品推荐

