使用MongoDB C#驱动单查询实现文档一对多关联映射查询
实现方案
核心依赖MongoDB原生的$lookup聚合能力,它天然支持本地字段为数组时的批量关联查询,整个流程仅会发起1次数据库请求,下面给出两种符合你编码习惯的实现:
方案1:LINQ 写法(与你单司机查询风格对齐)
public TruckManyDriversDTO GetTruckManyDriversDTO(string truckId) { var trucks = mongo.GetDatabase("mydb").GetCollection<TruckManyDrivers>("Trucks"); var drivers = mongo.GetDatabase("mydb").GetCollection<Driver>("Drivers"); return trucks.AsQueryable() .Where(truck => truck.Id == truckId) // GroupJoin会被MongoDB LINQ提供器自动转换为$lookup聚合 .GroupJoin( drivers.AsQueryable(), truck => truck.DriversIds, driver => driver.Id, (truck, matchedDrivers) => new TruckManyDriversDTO { Id = truck.Id, Drivers = matchedDrivers } ) .ToEnumerable() // 和单司机查询逻辑保持一致,避免驱动隐式转换异常 .Single(); }
方案2:原生聚合管道写法(性能更可控)
如果你希望更直接控制聚合行为,可以直接用驱动提供的聚合API:
public TruckManyDriversDTO GetTruckManyDriversDTO(string truckId) { var trucks = mongo.GetDatabase("mydb").GetCollection<TruckManyDrivers>("Trucks"); var drivers = mongo.GetDatabase("mydb").GetCollection<Driver>("Drivers"); return trucks.Aggregate() // 先过滤匹配指定ID的货车文档 .Match(t => t.Id == truckId) // 直接关联Driver集合,将匹配的Driver列表直接映射到DTO的Drivers字段 .Lookup<TruckManyDrivers, Driver, TruckManyDriversDTO>( foreignCollection: drivers, localField: t => t.DriversIds, foreignField: d => d.Id, asField: dto => dto.Drivers ) .Single(); }
注意事项
- 该实现依赖MongoDB 3.2+版本提供的
$lookup能力,官方C#驱动版本≥2.5即可完美支持 - 关联查询的性能和
Driver集合的Id字段索引有关,默认Id是主键索引,无需额外配置即可保证查询效率
内容的提问来源于stack exchange,提问作者Ran Karat
相关产品推荐
相关产品推荐

