简体   繁体   English

MongoDB:查询参考文档

[英]MongoDB: Querying for a referenced document

I am new to MongoDB and I read the MongoDB documentation. 我是MongoDB的新手,我阅读了MongoDB文档。 I have following structure: - 我有以下结构:-

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; }
}

I referenced Gateway MAC Addresses in the USER document as Gateway is also having separate existence in absence of USER. 我在USER文档中引用了网关MAC地址,因为在没有USER的情况下,网关也单独存在。 For getting all the gateways for a given UserId I am writing queries as follows: - 为了获取给定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));

But I am getting an Exception that 但是我得到一个例外

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

But when I write my query as follows all goes well 但是当我按照以下方式编写查询时,一切顺利

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));

I just want to know the difference between the above two. 我只想知道以上两者之间的区别。

The difference is that the MongoDB C# driver can't translate the first snippet into a MongoDB query, while it can the second one. 区别在于MongoDB C#驱动程序无法将第一个代码片段转换为MongoDB查询,而可以将第二个代码片段转换为MongoDB查询。

When you call Where on an IQueryable it stores all the lambda expressions until you materialize the query be using foreach or ToList . 当您Where IQueryable上调用Where时,它将存储所有lambda表达式,直到使用foreachToList实现查询。 At that stage the provider (the driver) tries to generate relevant queries to be performed in the database. 在那个阶段,提供者(驱动程序)尝试生成要在数据库中执行的相关查询。

The database can't use userCursor.FirstOrDefault() as it doesn't know what FirstOfDefault is and it can't receive a cursor. 数据库无法使用userCursor.FirstOrDefault()因为它不知道FirstOfDefault是什么,并且无法接收游标。 It can however serialize a User instance that you have retrieved from the database previously. 但是,它可以序列化您以前从数据库中检索到的User实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM