Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/renovate.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"github>TurnerSoftware/.github:renovate-shared"
"config:recommended"
]
}
75 changes: 15 additions & 60 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ on:
push:
branches: [ main ]
pull_request:
release:
types: [ published ]

concurrency:
group: '${{github.workflow}} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
Expand All @@ -29,16 +27,13 @@ jobs:
strategy:
matrix:
os: [windows-latest, macOS-latest]
mongodb: ['4.4', '5.0', '6.0']
mongodb: ['7.0', '8.0']
include:
- os: ubuntu-20.04
mongodb: '4.4'
ubuntu: 'focal'
- os: ubuntu-20.04
mongodb: '5.0'
ubuntu: 'focal'
- os: ubuntu-latest
mongodb: '6.0'
mongodb: '7.0'
ubuntu: 'jammy'
- os: ubuntu-latest
mongodb: '8.0'
ubuntu: 'jammy'
steps:
- name: Configure MongoDB (MacOS)
Expand All @@ -48,11 +43,8 @@ jobs:
brew update
brew install mongodb-community@${{matrix.mongodb}}
brew services start mongodb-community@${{matrix.mongodb}}
- name: Configure MongoDB (Ubuntu (20.04))
if: matrix.os == 'ubuntu-20.04'
run: sudo apt remove mongodb-org
- name: Configure MongoDB (Ubuntu (All))
if: matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-20.04'
- name: Configure MongoDB (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
wget -qO - https://www.mongodb.org/static/pgp/server-${{matrix.mongodb}}.asc | gpg --dearmor | sudo tee /usr/share/keyrings/mongodb.gpg > /dev/null
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb.gpg ] https://repo.mongodb.org/apt/ubuntu ${{matrix.ubuntu}}/mongodb-org/${{matrix.mongodb}} multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-${{matrix.mongodb}}.list
Expand All @@ -70,23 +62,21 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Setup dotnet SDK
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
7.0.x
dotnet-version: 10.0.x
- name: Install dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore -c Release
- name: Test with Coverage
run: dotnet test --no-restore --logger trx --results-directory ${{env.BUILD_ARTIFACT_PATH}}/coverage --collect "XPlat Code Coverage" --settings CodeCoverage.runsettings /p:SkipBuildVersioning=true
run: dotnet test --no-restore --logger trx --results-directory ${{env.BUILD_ARTIFACT_PATH}}/coverage --collect "XPlat Code Coverage" --settings CodeCoverage.runsettings
- name: Pack
run: dotnet pack --no-build -c Release /p:PackageOutputPath=${{env.BUILD_ARTIFACT_PATH}}
- name: Publish artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{matrix.os}}
name: ${{matrix.os}}-mongo${{matrix.mongodb}}
path: ${{env.BUILD_ARTIFACT_PATH}}

coverage:
Expand All @@ -97,54 +87,19 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Download coverage reports
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
- name: Install ReportGenerator tool
run: dotnet tool install -g dotnet-reportgenerator-globaltool
- name: Prepare coverage reports
run: reportgenerator -reports:*/coverage/*/coverage.cobertura.xml -targetdir:./ -reporttypes:Cobertura
- name: Upload coverage report
uses: codecov/codecov-action@v3.1.4
uses: codecov/codecov-action@v4
with:
file: Cobertura.xml
fail_ci_if_error: false
- name: Save combined coverage report as artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: Cobertura.xml

push-to-github-packages:
name: 'Push GitHub Packages'
needs: build
if: github.ref == 'refs/heads/main' || github.event_name == 'release'
environment:
name: 'GitHub Packages'
url: https://github.com/TurnerSoftware/MongoFramework/packages
permissions:
packages: write
runs-on: ubuntu-latest
steps:
- name: 'Download build'
uses: actions/download-artifact@v3
with:
name: 'ubuntu-latest'
- name: 'Add NuGet source'
run: dotnet nuget add source https://nuget.pkg.github.com/TurnerSoftware/index.json --name GitHub --username Turnerj --password ${{secrets.GITHUB_TOKEN}} --store-password-in-clear-text
- name: 'Upload NuGet package'
run: dotnet nuget push *.nupkg --api-key ${{secrets.GH_PACKAGE_REGISTRY_API_KEY}} --source GitHub --skip-duplicate

push-to-nuget:
name: 'Push NuGet Packages'
needs: build
if: github.event_name == 'release'
environment:
name: 'NuGet'
url: https://www.nuget.org/packages/MongoFramework
runs-on: ubuntu-latest
steps:
- name: 'Download build'
uses: actions/download-artifact@v3
with:
name: 'ubuntu-latest'
- name: 'Upload NuGet package'
run: dotnet nuget push *.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{secrets.NUGET_API_KEY}}
51 changes: 51 additions & 0 deletions .github/workflows/publish-nuget.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Note this will only work with Release-Please if you have given it a PAT.
# The default GITHUB_TOKEN does not have permission to run workflows on releases
name: Publish to NuGet

on:
release:
types: [published]
workflow_dispatch:

permissions:
id-token: write # Required for OIDC
contents: read

env:
DOTNET_NOLOGO: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_CLI_TELEMETRY_OPTOUT: true

jobs:
release:
runs-on: ubuntu-latest
environment:
name: 'NuGet'
url: https://www.nuget.org/packages/MongoFramework
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Setup DotNet
uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x

- name: Install dependencies
run: dotnet restore

- name: Build
run: dotnet build --no-restore -c Release

- name: Pack NuGet
run: dotnet pack --no-build -c Release -o nupkg

# Get a short-lived NuGet API key
- name: NuGet login (OIDC)
uses: NuGet/login@v1
id: login
with:
user: ${{ secrets.NUGET_USER }}

- name: Push NuGet
run: dotnet nuget push nupkg/*.nupkg -k ${{ steps.login.outputs.NUGET_API_KEY }} -s https://api.nuget.org/v3/index.json --skip-duplicate
20 changes: 20 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
on:
push:
branches:
- main
workflow_dispatch:

permissions:
contents: write
issues: write
pull-requests: write

name: release-please

jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,9 @@ paket-files/

# MacOS
.DS_Store

benchmark-results-v2/

benchmark-results-v3/

BenchmarkDotNet.Artifacts/
3 changes: 3 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "3.0.0"
}
35 changes: 25 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@

![Icon](images/icon.png)
# MongoFramework
An "Entity Framework"-like interface for MongoDB

![Build](https://img.shields.io/github/actions/workflow/status/TurnerSoftware/mongoframework/build.yml?branch=main)
[![Codecov](https://img.shields.io/codecov/c/github/turnersoftware/mongoframework/main.svg)](https://codecov.io/gh/TurnerSoftware/MongoFramework)
[![NuGet](https://img.shields.io/nuget/v/MongoFramework.svg)](https://www.nuget.org/packages/MongoFramework/)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/62fa31c90bf94f3d8e201b9684a7a4ca)](https://www.codacy.com/app/Turnerj/MongoFramework)
![Build](https://img.shields.io/github/actions/workflow/status/jcamp-code/MongoFramework/build.yml?branch=main)
[![Codecov](https://img.shields.io/codecov/c/github/jcamp-code/MongoFramework/main.svg)](https://codecov.io/gh/jcamp-code/MongoFramework)
[![NuGet](https://img.shields.io/nuget/v/jcamp.MongoFramework.svg)](https://www.nuget.org/packages/jcamp.MongoFramework/)
</div>

## Fork
Note this is a fork from the original, updated for latest .NET versions and packages.

Version has been set to v3 to indicate compatibility with the v3 MongoDB CS driver.

An "Entity Framework"-like interface for MongoDB


## Overview
MongoFramework tries to bring some of the nice features from Entity Framework into the world of MongoDB.

Expand All @@ -25,13 +31,22 @@ Some of the major features include:

MongoFramework is currently built on-top of the official MongoDB C# driver.

## Licensing and Support
## Performance

MongoFramework is licensed under the MIT license. It is free to use in personal and commercial projects.
MongoFramework with MongoDB.Driver 3.x and .NET 10 delivers significant performance improvements:

| Category | Speed Improvement | Memory Reduction |
|----------|-------------------|------------------|
| LINQ Operations | ~66% faster | ~55% less |
| Entity Mapping | ~53% faster | ~10% less |
| Serialization | ~47% faster | ~6% less |
| Database Operations | ~84% faster | ~26% less |

Benchmarks performed comparing MongoDB.Driver 2.x (.NET 6) vs 3.x (.NET 10). See [benchmark results](tests/MongoFramework.Benchmarks) for details.

There are [support plans](https://turnersoftware.com.au/support-plans) available that cover all active [Turner Software OSS projects](https://github.com/TurnerSoftware).
Support plans provide private email support, expert usage advice for our projects, priority bug fixes and more.
These support plans help fund our OSS commitments to provide better software for everyone.
## Licensing

MongoFramework is licensed under the MIT license. It is free to use in personal and commercial projects.

## MongoFramework Extensions
These extensions are official packages that enhance the functionality of MongoFramework, integrating it with other systems and tools.
Expand Down
97 changes: 97 additions & 0 deletions docs/MONGODB_DRIVER_3_MIGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# MongoDB.Driver 3.x Migration Guide

This document describes the changes when upgrading MongoFramework to use MongoDB.Driver 3.6.0 (from 2.21.0).

## Overview

MongoDB.Driver 3.0 removes the LINQ2 provider entirely and makes LINQ3 the only option. MongoFramework has been updated to work seamlessly with LINQ3.

## LINQ3 Compatibility

All common LINQ patterns work correctly with LINQ3:

| Pattern | Example | Status |
|---------|---------|--------|
| `Any()` with predicate | `dbSet.Any(x => x.Name == "test")` | **Supported** |
| `FirstOrDefault()` with predicate | `dbSet.FirstOrDefault(x => x.Id == id)` | **Supported** |
| `First()` with predicate | `dbSet.First(x => x.Id == id)` | **Supported** |
| `SingleOrDefault()` with predicate | `dbSet.SingleOrDefault(x => x.Id == id)` | **Supported** |
| `Single()` with predicate | `dbSet.Single(x => x.Id == id)` | **Supported** |
| `Where().FirstOrDefault()` | `dbSet.Where(x => x.Id == id).FirstOrDefault()` | **Supported** |
| `Count()` with predicate | `dbSet.Count(x => x.Active)` | **Supported** |

## Breaking Changes

### 1. DateTime Handling

MongoDB.Driver 3.x returns `DateTime` values in UTC. For consistent round-tripping, use UTC explicitly:

```csharp
// Recommended: Use UTC for dates
var date = new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Utc);
```

Dates stored with `DateTimeKind.Unspecified` will be treated as local time, converted to UTC for storage, and returned as UTC.

### 2. GUID Serialization

MongoDB.Driver 3.x requires explicit `GuidRepresentation`. MongoFramework now configures `GuidRepresentation.Standard` (UUID binary subtype 4) by default for cross-platform compatibility.

If you were using a different GUID representation, you may need to migrate existing data or configure a different serializer.

### 3. Render() Method Signature (Internal)

If you use MongoDB driver APIs directly, the `Render()` method on definition builders now requires `RenderArgs<T>`:

```csharp
// Before
definition.Render(serializer, registry);

// After
var renderArgs = new RenderArgs<TEntity>(serializer, registry);
definition.Render(renderArgs);
```

### 4. IMongoClient is now IDisposable

`MongoClient` now implements `IDisposable`. MongoFramework's `MongoDbConnection.Dispose()` properly disposes the underlying client.

### 5. Index Options

The `Background` property on `CreateIndexOptions` is deprecated (since MongoDB 4.2). Index builds are now automatically optimized by the server.

## Migration Steps

1. Update the MongoFramework NuGet package to the version using MongoDB.Driver 3.6.0
2. Review any code that uses `DateTime` values - ensure UTC is used for consistent behavior
3. Run your test suite - most LINQ queries should work without changes
4. Review any direct MongoDB driver API usage for `Render()` signature changes

## Troubleshooting

### ExpressionNotSupportedException

If you encounter `ExpressionNotSupportedException`, it indicates a query pattern that LINQ3 cannot translate to the aggregation pipeline. Common solutions:

1. **Simplify the expression** - Break complex queries into simpler steps
2. **Use supported alternatives** - Some projections may need adjustment
3. **Fetch and filter in-memory** - For edge cases, fetch results first then filter

Example:
```csharp
// If a complex expression fails, try fetching first
var results = dbSet.Where(x => x.Category == "Active").ToArray();
var filtered = results.Where(x => ComplexCondition(x));
```

### DateTime Mismatch

If dates appear shifted by your timezone offset:
- Ensure you're using `DateTimeKind.Utc` when creating dates
- Consider using `DateTimeOffset` for timezone-aware timestamps

## Resources

- [MongoDB Driver Upgrade Guide](https://www.mongodb.com/docs/drivers/csharp/current/reference/upgrade/v3/)
- [LINQ3 Documentation](https://www.mongodb.com/docs/drivers/csharp/current/aggregation/linq/)
- [Breaking Changes in v3.0](https://www.mongodb.com/docs/drivers/csharp/v3.0/reference/release-notes/)
13 changes: 13 additions & 0 deletions dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": 1,
"isRoot": true,
"tools": {
"csharpier": {
"version": "1.2.5",
"commands": [
"csharpier"
],
"rollForward": false
}
}
}
Loading
Loading