如何在MongoDB C#驱动中使用投影?含忽略_id的代码实现
Hey there! Let's tackle your two MongoDB C# driver projection questions step by step with practical code examples. I'll use a simple Product entity class for consistency across examples:
public class Product { public ObjectId Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public string Category { get; set; } }
Projection lets you fetch only specific fields from your documents instead of the entire document, which saves bandwidth and improves performance. There are two common approaches to implement this:
Using the Builders<T>.Projection API
This method gives you fine-grained control over which fields to include or exclude. Here's an example where we only retrieve the Name and Price fields from products in the "Electronics" category:
var collection = mongoDatabase.GetCollection<Product>("products"); // Define the projection: include Name and Price var projection = Builders<Product>.Projection .Include(p => p.Name) .Include(p => p.Price); // Execute the query with projection var results = await collection.Find(p => p.Category == "Electronics") .Project(projection) .ToListAsync();
Using Projection Expressions (Concise Syntax)
For simpler scenarios, you can use a lambda expression directly in the Project() method to define the fields you want. This will automatically create a projection that only includes the specified fields:
var results = await collection.Find(p => p.Category == "Electronics") .Project(p => new { p.Name, p.Price }) // Project to an anonymous type .ToListAsync();
You can also project to a custom DTO (Data Transfer Object) if you want a strongly-typed result instead of an anonymous type:
public class ProductSummary { public string Name { get; set; } public decimal Price { get; set; } } var results = await collection.Find(p => p.Category == "Electronics") .Project<ProductSummary>(p => new ProductSummary { Name = p.Name, Price = p.Price }) .ToListAsync();
_id Field in Projection By default, MongoDB returns the _id field even if you don't explicitly include it in your projection. To exclude it, you have a couple of options depending on which projection approach you're using:
With Builders<T>.Projection API
Use the Exclude() method to explicitly exclude the _id field. Here's an example where we fetch Name and Category without the _id:
var projection = Builders<Product>.Projection .Include(p => p.Name) .Include(p => p.Category) .Exclude(p => p.Id); // Exclude the _id field var results = await collection.Find(_ => true) .Project(projection) .ToListAsync();
With Projection Expressions
When using a projection expression (to anonymous type or DTO), you just need to not include the Id property in your projection. The MongoDB driver will automatically exclude _id in this case:
// Project to anonymous type (no Id, so _id is excluded) var results = await collection.Find(_ => true) .Project(p => new { p.Name, p.Category }) .ToListAsync(); // Or project to a DTO that doesn't have an Id property public class ProductCategoryView { public string Name { get; set; } public string Category { get; set; } } var results = await collection.Find(_ => true) .Project<ProductCategoryView>(p => new ProductCategoryView { Name = p.Name, Category = p.Category }) .ToListAsync();
Note:
If you're using projection expressions and do include the Id property, it will be mapped to the _id field as expected. Only when you omit it does the driver exclude _id from the result.
内容的提问来源于stack exchange,提问作者Guru Ganesh

