Reputation: 4009
I have a .NET Application that uses a MongoDB so I am using mongo c# driver. Current version I am using is 1.9.2.
I am trying to update this to latest C# mongodb driver - 2.7.0. I have had to make numerous code changes so far for breaking changes. I am stumped with a few at the minute - may raise new questions for the others in due course but the one below has been causing the App to not even load when debugging.
This was my original code with the 1.9.2 driver:
/// <summary>
/// Since the current Mongo driver does not support database side Select
/// projections, we need to use this custom function to achieve the same.
/// </summary>
/// <param name="criteria"></param>
/// <param name="fields"></param>
/// <returns></returns>
public IEnumerable<T> Get(Expression<Func<T, bool>> criteria,
params Expression<Func<T, object>>[] fields)
{
return this.Collection.FindAs<T>(Query<T>.Where(criteria)).SetFields
(Fields<T>.Include(fields));
}
This is what I have attempted with the latest C# driver:
/// <summary>
/// Since the current Mongo driver does not support database side Select
/// projections, we need to use this custom function to achieve the same.
/// </summary>
/// <param name="criteria"></param>
/// <param name="fields"></param>
/// <returns></returns>
public IEnumerable<T> Get(Expression<Func<T, bool>> criteria,
params Expression<Func<T, object>>[] fields)
{
return this.Collection.Find<T>(criteria).Project(Builders<T>.Projection.Include(FilterDefinitionBuilder<T>.(fields)));
}
however I am getting a red build error on the .(fields))); saying incorrect primary expression but not sure what the correct fix is for this.
UPDATE
I added the code from mickl answer below and now when run the app I am getting the following exception:
"An error occurred while deserializing the Id property of class MyApp.Domain.Models.EntityBase: Cannot deserialize a 'String' from BsonType 'ObjectId'."
I had a BsonClassRegistration class with my old C# Driver Mongo code - the original code in it was below:
BsonClassMap.RegisterClassMap<EntityBase>(cm =>
{
cm.AutoMap();
cm.SetIdMember(cm.GetMemberMap(x => x.Id).SetIdGenerator(StringObjectIdGenerator.Instance));
cm.GetMemberMap(c => c.Id).SetRepresentation(BsonType.ObjectId);
});
To fix this with the upgrade to the latest C# driver I changed the code to the below:
BsonClassMap.RegisterClassMap<EntityBase>(cm =>
{
cm.AutoMap();
cm.SetIdMember(cm.GetMemberMap(x => x.Id).SetIdGenerator(StringObjectIdGenerator.Instance));
cm.GetMemberMap(c => c.Id).SetSerializer(new StringSerializer(BsonType.ObjectId));
});
Would this be the reason for the failure I am now seeing in the Get method
Upvotes: 1
Views: 668
Reputation: 49945
You can use Builders<T>.Projection
just like you tried but you have to dynamically build ProjectionDefinition<T>
instance which can be done like below:
public IEnumerable<T> Get(Expression<Func<T, bool>> criteria, params Expression<Func<T, object>>[] fields)
{
var find = Collection.Find<T>(criteria);
var builder = Builders<T>.Projection;
var definition = (ProjectionDefinition<T>)null;
foreach(var field in fields)
{
definition = definition?.Include(field) ?? builder.Include(field);
}
if (definition == null) return find.ToList();
return find.Project<T>(definition).ToList();
}
Upvotes: 1