I have the following structure:
public abstract class DbEntity
{
[BsonId]
public ObjectId Id { get; set; }
[BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
public DateTime CreatedAt { get; set; }
[BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
public DateTime ModifiedAt { get; set; }
[BsonDefaultValue(EntityState.Active)]
public EntityState State { get; set; }
[BsonIgnoreIfNull]
[BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
public DateTime? DeletedOn { get; set; }
}
public class Post : DbEntity
{
public ObjectId UserId { get; set; }
public string SourceUrl { get; set; }
public Guid? PictureId { get; set; }
public PostType Type { get; set; }
public string Caption { get; set; }
public GeoJsonPoint<GeoJson2DGeographicCoordinates> Location { get; set; }
public string LocationName { get; set; }
public List<ObjectId> TaggedFriends { get; set; }
public List<string> Tags { get; set; }
public List<string> GearTags { get; set; }
public Activity Activity { get; set; }
public int LikesAmount { get; set; }
public int CommentsAmount { get; set; }
public List<SharingTarget> Shared { get; set; }
public List<string> SearchTokens
{
get
{
var result = new List<string>();
result.AddRange(Caption.GetTokens());
result.AddRange(Tags);
result.AddRange(GearTags);
result.AddRange(LocationName.GetTokens());
return result;
}
set { }
}
}
private class AggregatedPost : Followings
{
public AggregatedPost(ObjectId ownerId) : base(ownerId)
{
}
public List<Post> Posts { get; set; }
}
private class UnwindPost : Followings
{
public UnwindPost(ObjectId ownerId) : base(ownerId)
{
}
public Post Posts { get; set; }
}
I run the query where as a projection I use an Expression <Func<UnwindPost,Post>>
var query = await
followingsCollection.Aggregate()
.Match(Builders<Followings>.Filter.Where(v => v.Id == userId))
.Unwind<Followings>(new ExpressionFieldDefinition<Followings>(LocalFollowingFieldName))
.Lookup(postCollection, new ExpressionFieldDefinition<Followings>(LocalFollowingFieldName), new ExpressionFieldDefinition<Post>(ForeignPostFieldName),
new ExpressionFieldDefinition<AggregatedPost>(AggregatedPostAliasFieldName))
.Unwind<UnwindPost>(new ExpressionFieldDefinition<AggregatedPost>(UnwindPostFieldName))
.Limit(pageInfo.Take)
.Skip(pageInfo.Skip)
.Project(v => new Post
{
Id = v.Posts.Id,
UserId = v.Posts.UserId,
CreatedAt = v.Posts.CreatedAt,
SourceUrl = v.Posts.SourceUrl,
Type = v.Posts.Type,
Caption = v.Posts.Caption,
Activity = v.Posts.Activity,
LocationName = v.Posts.LocationName,
LikesAmount = v.Posts.LikesAmount,
CommentsAmount = v.Posts.CommentsAmount,
PictureId = v.Posts.PictureId
}).ToListAsync();
As a result I have an exception that says Element 'Id' does not match any field or property of class. If I run this query on mongodb, it returns the next record:
Id: ObjectId("57d91c5393846c3c14792522")
UserId: ObjectId("57d91c5293846c3c14792512")
CreatedAt: 09/14/2016 12:45:55 PM (+0300)
SourceUrl: "test url"
Type: 0
Caption: "Test1"
Activity: NULL
LocationName: "TestLocationName"
LikesAmount: 0
CommentsAmount: 0
PictureId: NULL
As you may see, there is no field _id
here, however id is returned as Id
. All my records are stored in mongodb with _id
field.
How can I project the record with _id
field in mongo syntax that will be mapped correctly to my Post class (preferably using projection that has Expression as an argument)?