MongoDB .NET/C# Driver

repository·main·Indexed 25 days ago

https://github.com/mongodb/mongo-csharp-driver

The official MongoDB .NET/C# driver for connecting to and interacting with MongoDB databases. It supports strongly-typed POCOs and untyped BSON documents via the MongoDB.Bson and MongoDB.Driver namespaces. Key features include LINQ support, Client-Side Field Level Encryption (CSFLE), GridFS, Atlas Search integration, and AWS IAM-based authentication.

Tokens
16K
Snippets
21
Records
137
Agent score
85%

What's inside mongo-csharp-driver

  1. Understand Connection Monitoring and Pooling Concepts

    main

    In the context of the MongoDB C# Driver, it is important to distinguish between different networking and pooling concepts:

    • Connection: Refers to the driver's internal Connection type. It is an abstraction that manages the lifecycle of a TCP connection to an endpoint. A Connection object is not identical to a TCP connection; it may exist without an active TCP connection at all times.
    • Endpoint: Refers to either a mongod or mongos instance.
    • Thread: In the context of the C# driver, this refers to a shared-address-space process (a thread).
  2. Understand the MongoDB C# Driver Agent-Aware Architecture

    main
    The repository is partitioned into functional areas to support agent-aware tooling (like Claude Code). Each area contains its own AGENTS.md file for specific context and a CLAUDE.md file that acts as a pointer to it. This architecture ensures that when working on specific parts of the driver (e.g., BSON serialization, LINQ, or GridFS), the relevant invariants, pitfalls, and review checklists are surfaced without overwhelming the developer with unrelated context.
  3. Understand Connection Pool Behavior and Lifecycle

    main

    The MongoDB C# Driver manages connections through a Connection Pool associated with a single endpoint.

    Key Pool Behaviors

    • Thread Safety: All pool operations are thread-safe.
    • Capped Pools: If maxPoolSize is set to a non-zero value, the total number of connections (in use + available) will not exceed this limit.
    • Rate Limiting: The pool limits concurrent connection establishment using the maxConnecting option.
    • Closing and Clearing:
      • When a pool is closed, checking in a connection automatically closes it, and attempting to check out a connection results in an error.
      • When a pool is cleared, all connections (pooled and checked out) are marked as stale and lazily closed. All requests in the WaitQueue are evicted with non-timeout network errors.
    • Pausing: A pool can be paused (e.g., during a clear operation). While paused, checking out a connection results in a non-timeout network error, and background connection creation for minPoolSize is suspended.
  4. Add a New Functional Area to the Agent Architecture

    main

    To introduce a new functional area for agent-aware tooling, follow these steps:

    1. Select a directory root: Pick a natural directory or a glob set for the area.
    2. Create documentation files:
      • Create AGENTS.md in the directory using the standard skeleton (including YAML frontmatter with area, scope, reviewer-agent, and adjacent-areas).
      • Create a sibling CLAUDE.md containing exactly one line: @AGENTS.md.
    3. Create a reviewer sub-agent:
      • Add a file at .claude/agents/<name>-reviewer.md following the sub-agent skeleton.
    4. Update central registries:
      • Add a row to the Functional areas table in the root AGENTS.md.
      • Add a path-pattern row for the new reviewer in .claude/commands/review-areas.md to enable automatic dispatch via the /review-areas skill.
    5. Verify:
      • Confirm the auto-load chain works in a fresh agent session.
      • Ensure find . -name CLAUDE.md shows the correct one-line pointers.
      • Run the dotnet test --filter command specified in your new area's AGENTS.md to ensure test-filter sanity.
  5. Handle connection timeouts using client-side mechanisms

    main
    The driver avoids implementing granular controls like waitQueueTimeoutMS in favor of a single, unified client-side timeout mechanism. If you need to implement timeouts for operations waiting on connections, leverage the idiomatic timeout mechanisms already available in your application or the driver's client-side operation timeout specification.
  6. Configure Medium Trust permissions for the C# Driver

    main

    In vanilla medium trust environments, TCP communication is disallowed. To enable the driver to run, you must use a custom medium trust permission system that allows sockets. Copy your existing medium trust policy file and add the following configurations:

    1. Add the SocketPermission security class.
    2. Add an IPermission for the new SocketPermission class.
    <SecurityClass Name="SocketPermission" Description="System.Net.SocketPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    
    <IPermission class="SocketPermission" version="1" Unrestricted="true"/>
  7. Use MongoClient for Acknowledged WriteConcern

    main

    Starting with version 1.7, the default WriteConcern has changed to Acknowledged. To use this new default, you must use the MongoClient class.

    If you continue to use the deprecated MongoServer.Create method, the WriteConcern will remain Unacknowledged to maintain backward compatibility with existing code.

    // The new way (defaults WriteConcern to Acknowledged)
    var connectionString = "mongodb://localhost";
    var client = new MongoClient(connectionString);
    var server = client.GetServer();
    var database = server.GetDatabase("test");
    
    // The old way (deprecated, defaults WriteConcern to Unacknowledged)
    var connectionString = "mongodb://localhost";
    var server = MongoServer.Create(connectionString); // deprecated
    var database = server.GetDatabase("test");
  8. Export and Compare Benchmark Results

    main

    To facilitate automated analysis or comparison, you can export results in the Evergreen format.

    Exporting Results

    Use the --evergreen option. You can specify a custom output filename using --output or -o. The default filename is evergreen-results.json.

    dotnet run -c Release -- --driverBenchmarks --evergreen --output "my-results.json"

    All output files (logs, exported JSON, etc.) are stored in a BenchmarkDotNet.Artifacts folder created after execution.

    Comparing Runs

    Use the Python script located in /scripts/compare-results to compare different benchmark runs. This script requires JSON files generated with the --evergreen option.

  9. Run the C# Driver Benchmark Suite

    main

    To run the driver benchmarks, you must first download the required data and ensure a mongod instance is running on localhost. You can specify a custom connection string using the MONGODB_URI environment variable or the --envVars option.

    Prerequisites

    1. Download benchmark data: Run /scripts/download-data.sh from the benchmark root directory.
    2. Ensure a MongoDB instance is running (default: localhost).

    Execution

    Run the following command to start the runner with an interactive prompt to select benchmarks:

    dotnet run -c Release -- --driverBenchmarks

    To specify a custom connection string via command line arguments:

    dotnet run -c Release -- --driverBenchmarks --envVars MONGODB_URI:"ConnectionString"
    dotnet run -c Release -- --driverBenchmarks
  10. Use Insert or Update instead of Save for better performance

    main

    The Save method was updated in version 1.8.3 to ensure correct _id serialization when using custom serializers. Because this new approach is slightly less efficient, you can achieve better performance by calling Insert or Update directly:

    • Use Insert if you know the document is new.
    • Use Update with an appropriate query and the Upsert flag if you are unsure whether the document exists.