5

With the old driver I could specify the fields I wanted to return from a query as follows:

var cursor = Collection.Find(query).
  SetFields(Fields<MealPlan>.Exclude (plan => plan.Meals));

How do I accomplish this with the 2.0 driver?

2 Answers 2

4

You need to use the Projection method on IFindFluent (which is what Find and Projection return):

var findFluent = Collection.Find(query).Projection(Fields<MealPlan>.Exclude (plan => plan.Meals))

Now, this would eventually generate a cursor of BsonDocuments since it doesn't know how the projection looks. You can call the generic Projection instead to add that type:

var findFluent = Collection.Find(query).Projection<MealPlan>(Fields<MealPlan>.Exclude (plan => plan.Meals))

In a more general sense (which is less relevant when using Exclude), you could also specify fields using a lambda expression:

var findFluent = Collection.Find(query).Projection(plan => plan.Meals)
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks. I know the driver is in beta, but will the generic projection support abstract classes? I'm assuming the serializer has access to the discriminator to determine the concrete type.
What exactly do you mean?
@Graeme Do you mean something like Collection.Find(query).Projection<AbstractPlan>(Fields.Include("_id"))? No, it won't work as it tries to create an instance out of AbstractPlan. It can work if the base class isn't abstract but the instance would be of the base class and not the concrete type.
Actually, I think that as long as the discriminator was there (in the projection), it should work. It would certainly come back typed as the base class and require a downcast, but underneath, in this case, we are just using the AbstractPlan serializer and it knows how to deal with discriminators. I haven't tried this though, so...
@CraigWilson just did. It does work when the discriminator is added (which unlike _id isn't returned by default from mongo)
|
1

If you want SetFields back you can write your own extension method:

 public static class MongoExtensions
{
    public static IFindFluent<T, T> SetFields<T>(this IFindFluent<T, T> query, params string[] fields)
    {
        if ( fields == null || fields.Length == 0 )
        {
            return query;
        }

        var project = Builders<T>.Projection.IncludeAll<T>(fields);

        return query.Project<T>(project);
    }


    public static ProjectionDefinition<T> IncludeAll<T>(this ProjectionDefinitionBuilder<T> projection,
        params string[] fields)
    {
        ProjectionDefinition<T> project = null;

        foreach (string columnName in fields)
        {
            if (project == null)
            {
                project = Builders<T>.Projection.Include(columnName);
            }
            else
            {
                project = project.Include(columnName);
            }
        }
        return project;

    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.