Reputation: 2016
I'm trying to join two collections by Id
. Although I can see rows in the database, the query results are empty.
I have two collections: userGames
and games
Here is my Code to join collections:
var userGamesQuery = userGames.AsQueryable()
.Where(x => x.UserId == userId);
var query = from userGame in userGamesQuery
join game in games.AsQueryable() on userGame.GameId equals game.Id
select game;
the first part returns 13 elements but the second part return nothing. I think the line userGame.GameId equals game.Id
has some problems. tried to use ObjectId.Parse()
on both userGame.GameId
and game.Id
but no luck.
Here are my Models
Game Class :
public class Game
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
}
UserGames :
public class UserGames
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string UserId { get; set; }
public string GameId { get; set; }
}
Upvotes: 2
Views: 776
Reputation: 49995
The issue is that when you run "join" it tries to run equality comparison on both fields on the database side. To consider two values equal MongoDB checks types first and ten values. Since GameId
is of type string
and Id
is stored as BsonId
there will be no match between those collections.
The easiest way to fix that would be to change your class into:
public class UserGames
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string UserId { get; set; }
[BsonRepresentation(BsonType.ObjectId)]
public string GameId { get; set; }
}
and run a script on your database to convert existing data. It can be something like:
db.UserGames.aggregate([
{ $addFields: { GameId: { $toObjectId: "$GameId" } } },
{ $out: "UserGames" }
])
You can also try to convert types using either $toObjectId or $toString directly in your aggregation but there's no easy and convenient way to do that using strongly typed driver API.
Upvotes: 3