Projections in Mongo C# — Digitteck
Projections in Mongo C#
dotnet·20 October 2019·3 min read

Projections in Mongo C#

MongoDB projections limit the fields returned by a query. In the C# driver you have several ways to define them — from strongly-typed lambda expressions to lower-level field include/exclude builders. All approaches are valid; which one you choose depends on whether you need shape transformation or just field filtering.

Expression Projection via Builders

The most concise option — Builders<T>.Projection.Expression accepts a lambda that maps the document to any anonymous type or DTO. The driver translates the lambda into a MongoDB projection automatically:

csharp
// Builders.Projection.Expression — project to a target shape using a lambda
var collection = db.GetCollection<Person>("people");

var result = await collection
    .Find(p => p.Age > 25)
    .Project(Builders<Person>.Projection.Expression(
        p => new { p.FirstName, p.LastName, p.Email }
    ))
    .ToListAsync();

FindExpressionProjectionDefinition

When you need to reuse the same projection or pass it around, FindExpressionProjectionDefinition<TDocument, TProjection> makes it a first-class object:

csharp
// FindExpressionProjectionDefinition — construct the projection explicitly
var projection = new FindExpressionProjectionDefinition<Person, PersonDto>(
    p => new PersonDto
    {
        FullName = p.FirstName + " " + p.LastName,
        Email    = p.Email,
    }
);

var result = await collection
    .Find(p => p.Age > 25)
    .Project(projection)
    .ToListAsync();

FindAsync with FindOptions

Pass the projection through FindOptions<TDocument, TProjection> when using the lower-level FindAsync overload. This is useful when you also need to control sort, limit, or skip in the same call:

csharp
// FindAsync with FindOptions — supply the projection as an option
var findOptions = new FindOptions<Person, PersonDto>
{
    Projection = Builders<Person>.Projection.Expression(
        p => new PersonDto
        {
            FullName = p.FirstName + " " + p.LastName,
            Email    = p.Email,
        }
    )
};

using var cursor = await collection.FindAsync(p => p.Age > 25, findOptions);
var result = await cursor.ToListAsync();

Include / Exclude Projection

For field-level control without a DTO transformation, the Include / Exclude builder methods work similarly to the raw MongoDB projection syntax. _id is included by MongoDB unless explicitly excluded:

csharp
// Include / Exclude projection — field-level control (returns BsonDocument by default)
// Include only specific fields (1 = include, 0 = exclude)
var includeProjection = Builders<Person>.Projection
    .Include(p => p.FirstName)
    .Include(p => p.Email)
    .Exclude(p => p.Id);   // MongoDB includes _id by default; exclude explicitly if unwanted

var result = await collection
    .Find(p => p.Age > 25)
    .Project<PersonDto>(includeProjection)
    .ToListAsync();

Tags

.NETC#MongoDB
digitteck

© 2026 Digitteck