我是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));
我只是想知道上述两者之间的区别。
答案 0 :(得分:1)
不同之处在于MongoDB C#驱动程序无法将第一个代码段转换为MongoDB查询,而第二个代码段可以转换为第二个代码段。
当您在Where
上调用IQueryable
时,它会存储所有lambda表达式,直到您使用foreach
或ToList
来实现查询。在该阶段,提供者(驱动程序)尝试生成要在数据库中执行的相关查询。
数据库无法使用userCursor.FirstOrDefault()
,因为它不知道FirstOfDefault
是什么,并且它无法接收光标。但是,它可以序列化您之前从数据库中检索过的User
实例。