简体   繁体   中英

MongoDB: Querying for a referenced document

I am new to MongoDB and I read the MongoDB documentation. 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. For getting all the gateways for a given UserId I am writing queries as follows: -

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.

When you call Where on an IQueryable it stores all the lambda expressions until you materialize the query be using foreach or ToList . 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. It can however serialize a User instance that you have retrieved from the database previously.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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