MongoDB: 查询引用文档

MongoDB: Querying for a referenced document

我是 MongoDB 的新手,我阅读了 MongoDB 文档。我有以下结构:-

public class User
{
    [BsonId]
    public long UserId { get; set; }        
    public string LoginId { get; set; }
    public string Password { get; set; }        
    public List<string> Gateways { get; set; }
}
public class Gateway
{
    [BsonId]
    public string MACAddress { get; set; }
    public string SerialNumber { get; set; }
    public List<Device> Devices { get; set; }
}

我在 USER 文档中引用了网关 MAC 地址,因为网关在没有 USER 的情况下也有单独的存在。为了获得给定 UserId 的所有网关,我正在编写如下查询:-

var userQuery = Query<User>.EQ(u => u.UserId, aUserId);
var userCursor = mMongoUserCollection.Find(userQuery);
var gateways = mMongoGatewayCollection.AsQueryable<Gateway>().Where(g => userCursor.FirstOrDefault().Gateways.Contains(g.MACAddress));

但是我得到一个异常

"Unable to determine Serialization Information for the expression: Enumerable.FirstOrDefault<User>"

但是当我如下编写查询时一切顺利

var userQuery = Query<User>.EQ(u => u.UserId, aUserId);
var userCursor = mMongoUserCollection.Find(userQuery);

List<string> desiredGateways = userCursor.FirstOrDefault().Gateways;
var gateways = mMongoGatewayCollection.AsQueryable<Gateway>().Where(g => desiredGateways.Contains(g.MACAddress));

我就是想知道上面两者的区别

不同之处在于 MongoDB C# 驱动程序无法将第一个片段转换为 MongoDB 查询,而第二个片段可以。

当您在 IQueryable 上调用 Where 时,它会存储所有 lambda 表达式,直到您使用 foreachToList 实现查询。在那个阶段,提供者(驱动程序)尝试生成要在数据库中执行的相关查询。

数据库无法使用 userCursor.FirstOrDefault(),因为它不知道 FirstOfDefault 是什么,也无法接收游标。但是,它可以序列化您之前从数据库中检索到的 User 实例。