├── .dockerignore
├── .gitattributes
├── .gitignore
├── .travis.yml
├── Blueshift.EntityFrameworkCore.sln
├── Blueshift.EntityFrameworkCore.sln.DotSettings
├── Directory.Build.props
├── Directory.Build.targets
├── LICENSE.txt
├── NuGet.config
├── README.md
├── appveyor.yml
├── build.cmd
├── build.sh
├── build
├── dependencies.props
├── repo.beforecommon.props
├── repo.props
├── repo.targets
└── sources.props
├── docker-compose.dcproj
├── docker-compose.yml
├── korebuild-lock.txt
├── korebuild.json
├── run.cmd
├── run.ps1
├── run.sh
├── src
├── Blueshift.EntityFrameworkCore.MongoDB.SampleDomain
│ ├── Blueshift.EntityFrameworkCore.MongoDB.SampleDomain.csproj
│ ├── ZooDbContext.cs
│ ├── ZooDbDependencyInjection.cs
│ ├── ZooEntityFixture.cs
│ └── _Comparers.cs
├── Blueshift.EntityFrameworkCore.MongoDB
│ ├── Adapter
│ │ ├── Conventions
│ │ │ ├── AbstractBaseClassConvention.cs
│ │ │ ├── BsonClassMapAttributeConvention.cs
│ │ │ ├── BsonMemberMapAttributeConvention.cs
│ │ │ ├── IgnoreEmptyEnumerablesConvention.cs
│ │ │ ├── IgnoreNullOrEmptyStringsConvention.cs
│ │ │ ├── KeyAttributeConvention.cs
│ │ │ ├── NavigationSrializationMemberMapConvention.cs
│ │ │ └── NotMappedAttributeConvention.cs
│ │ ├── EntityFrameworkConventionPack.cs
│ │ ├── Serialization
│ │ │ ├── BsonSerializerExtensions.cs
│ │ │ ├── DenormalizingBsonClassMapSerializer.cs
│ │ │ └── NavigationBsonMemberMapSerializer.cs
│ │ └── Update
│ │ │ ├── DeleteOneModelFactory.cs
│ │ │ ├── IMongoDbWriteModelFactory.cs
│ │ │ ├── IMongoDbWriteModelFactoryCache.cs
│ │ │ ├── IMongoDbWriteModelFactorySelector.cs
│ │ │ ├── InsertOneModelFactory.cs
│ │ │ ├── MongoDbWriteModelFactory.cs
│ │ │ ├── MongoDbWriteModelFactoryCache.cs
│ │ │ ├── MongoDbWriteModelFactorySelector.cs
│ │ │ └── ReplaceOneModelFactory.cs
│ ├── Annotations
│ │ ├── DenormalizeAttribute.cs
│ │ ├── MongoCollectionAttribute.cs
│ │ └── MongoDatabaseAttribute.cs
│ ├── Blueshift.EntityFrameworkCore.MongoDB.csproj
│ ├── ChangeTracking
│ │ └── MongoDbInternalEntityEntryFactory.cs
│ ├── DbContextOptionsExtensions.cs
│ ├── DependencyInjection
│ │ └── MongoDbEfServiceCollectionExtensions.cs
│ ├── Infrastructure
│ │ ├── EntityFrameworkMongoDbServicesBuilder.cs
│ │ ├── MongoDbContextOptionsBuilder.cs
│ │ ├── MongoDbContextOptionsBuilderExtensions.cs
│ │ ├── MongoDbModelValidator.cs
│ │ └── MongoDbOptionsExtension.cs
│ ├── ListExtensions.cs
│ ├── Metadata
│ │ ├── Builders
│ │ │ ├── DocumentDbInternalMetadataBuilderExtensions.cs
│ │ │ ├── DocumentEntityTypeBuilderExtensions.cs
│ │ │ ├── DocumentInternalKeyBuilderExtensions.cs
│ │ │ ├── MongoDbConventionSetBuilder.cs
│ │ │ ├── MongoDbConventionSetBuilderDependencies.cs
│ │ │ ├── MongoDbEntityTypeBuilderExtensions.cs
│ │ │ ├── MongoDbInternalMetadataBuilderExtensions.cs
│ │ │ └── MongoDbModelBuilderExtensions.cs
│ │ ├── Conventions
│ │ │ ├── BsonDiscriminatorAttributeConvention.cs
│ │ │ ├── BsonIgnoreAttributeConvention.cs
│ │ │ ├── BsonKnownTypesAttributeConvention.cs
│ │ │ ├── BsonRequiredAttributeConvention.cs
│ │ │ ├── DocumentPropertyMappingValidationConvention.cs
│ │ │ ├── MongoCollectionAttributeConvention.cs
│ │ │ ├── MongoDatabaseConvention.cs
│ │ │ ├── MongoDbDatabaseGeneratedAttributeConvention.cs
│ │ │ ├── MongoDbKeyAttributeConvention.cs
│ │ │ ├── MongoDbRelationshipDiscoveryConvention.cs
│ │ │ └── OwnedDocumentConvention.cs
│ │ ├── DocumentAnnotationNames.cs
│ │ ├── DocumentAnnotations.cs
│ │ ├── DocumentEntityTypeAnnotations.cs
│ │ ├── DocumentKeyAnnotations.cs
│ │ ├── MongoDbAnnotationNames.cs
│ │ ├── MongoDbEntityTypeAnnotations.cs
│ │ └── MongoDbModelAnnotations.cs
│ ├── MethodHelper.cs
│ ├── MongoDbUtilities.cs
│ ├── ObjectIdTypeConverter.cs
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ ├── Blueshift.EntityFrameworkCore.MongoDB.rd.xml
│ │ ├── DocumentDbStrings.Designer.cs
│ │ ├── DocumentDbStrings.cs
│ │ ├── DocumentDbStrings.resx
│ │ └── DocumentDbStrings.tt
│ ├── Query
│ │ ├── EntityLoadInfoFactory.cs
│ │ ├── ExpressionVisitors
│ │ │ ├── DocumentNavigationRewritingExpressionVisitor.cs
│ │ │ ├── DocumentNavigationRewritingExpressionVisitorFactory.cs
│ │ │ ├── IMongoDbDenormalizedCollectionCompensatingVisitorFactory.cs
│ │ │ ├── MongoDbDenormalizedCollectionCompensatingVisitor.cs
│ │ │ ├── MongoDbDenormalizedCollectionCompensatingVisitorFactory.cs
│ │ │ ├── MongoDbEntityQueryableExpressionVisitor.cs
│ │ │ ├── MongoDbEntityQueryableExpressionVisitorFactory.cs
│ │ │ ├── MongoDbMemberAccessBindingExpressionVisitor.cs
│ │ │ └── MongoDbMemberAccessBindingExpressionVisitorFactory.cs
│ │ ├── Expressions
│ │ │ ├── DocumentQueryExpression.cs
│ │ │ ├── IDocumentQueryExpressionFactory.cs
│ │ │ └── MongoDbDocumentQueryExpressionFactory.cs
│ │ ├── IEntityLoadInfoFactory.cs
│ │ ├── IValueBufferFactory.cs
│ │ ├── LinqQueryCompilationContextFactory.cs
│ │ ├── MongoDbEntityQueryModelVisitor.cs
│ │ ├── MongoDbEntityQueryModelVisitorDependencies.cs
│ │ ├── MongoDbEntityQueryModelVisitorFactory.cs
│ │ ├── MongoDbQueryBuffer.cs
│ │ ├── MongoDbQueryContext.cs
│ │ ├── MongoDbQueryContextFactory.cs
│ │ ├── QueryableLinqOperatorProvider.cs
│ │ └── ValueBufferFactory.cs
│ ├── Storage
│ │ ├── IMongoDbConnection.cs
│ │ ├── IMongoDbTypeMappingSource.cs
│ │ ├── MongoDbConnection.cs
│ │ ├── MongoDbDatabase.cs
│ │ ├── MongoDbDatabaseCreator.cs
│ │ └── MongoDbTypeMappingSource.cs
│ └── ValueGeneration
│ │ ├── HashCodeValueGenerator.cs
│ │ ├── IntegerValueGenerator.cs
│ │ ├── MongoDbValueGeneratorSelector.cs
│ │ └── ObjectIdValueGenerator.cs
├── Blueshift.Identity.MongoDB
│ ├── Blueshift.Identity.MongoDB.csproj
│ ├── DependencyInjection
│ │ └── IdentityEntityFrameworkMongoDbBuilderExtensions.cs
│ ├── IdentityMongoDbContext.cs
│ ├── MongoDbIdentityClaim.cs
│ ├── MongoDbIdentityRole.cs
│ ├── MongoDbIdentityUser.cs
│ ├── MongoDbIdentityUserLogin.cs
│ ├── MongoDbIdentityUserRole.cs
│ ├── MongoDbIdentityUserToken.cs
│ ├── MongoDbRoleStore.cs
│ └── MongoDbUserStore.cs
├── Directory.Build.props
└── Shared
│ ├── Check.cs
│ ├── CodeAnnotations.cs
│ ├── MemberInfoExtensions.cs
│ ├── PropertyInfoExtensions.cs
│ ├── SharedTypeExtensions.cs
│ └── StringBuilderExtensions.cs
├── test
├── Blueshift.EntityFrameworkCore.MongoDB.Tests
│ ├── Adapter
│ │ ├── Conventions
│ │ │ ├── AbstractClassConventionTest.cs
│ │ │ ├── IgnoreEmptyEnumerablesConventionTests.cs
│ │ │ ├── IgnoreNullOrEmptyStringsConventionTests.cs
│ │ │ └── KeyAttributeConventionTests.cs
│ │ ├── EntityFrameworkConventionPackTests.cs
│ │ ├── Serialization
│ │ │ ├── BsonSerializerExtensionsTests.cs
│ │ │ └── DenormalizingBsonClassMapSerializerTests.cs
│ │ └── Update
│ │ │ └── MongoDbWriteModelFactoryTests.cs
│ ├── ApiConsistencyTest.cs
│ ├── Blueshift.EntityFrameworkCore.MongoDB.Tests.csproj
│ ├── Metadata
│ │ ├── Conventions
│ │ │ └── MongoDatabaseConventionTests.cs
│ │ ├── MongoDbEntityTypeAnnotationsTests.cs
│ │ └── MongoDbModelAnnotationsTests.cs
│ ├── MongoDbContextTestBase.cs
│ ├── MongoDbContextTests.cs
│ ├── MongoDbUtilitiesTests.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Storage
│ │ ├── MongoDbConnectionTests.cs
│ │ ├── MongoDbDatabaseCreatorTests.cs
│ │ ├── MongoDbDatabaseTests.cs
│ │ └── MongoDbTypeMappingSourceTests.cs
│ ├── ValueGeneration
│ │ ├── MongoDbValueGeneratorSelectorTests.cs
│ │ └── ObjectIdValueGeneratorTests.cs
│ └── xunit.runner.json
├── Blueshift.Identity.MongoDB.Tests
│ ├── Blueshift.Identity.MongoDB.Tests.csproj
│ ├── MongoDbIdentityFixture.cs
│ ├── MongoDbIdentityTestBase.cs
│ ├── MongoDbIdentityTestCollection.cs
│ ├── MongoDbRoleClaimStoreTests.cs
│ ├── MongoDbRoleStoreTests.cs
│ ├── MongoDbUserAuthenticationTokenStoreTests.cs
│ ├── MongoDbUserAuthenticatorKeyStoreTests.cs
│ ├── MongoDbUserClaimStoreTests.cs
│ ├── MongoDbUserEmailStoreTests.cs
│ ├── MongoDbUserLockoutStoreTests.cs
│ ├── MongoDbUserLoginStoreTests.cs
│ ├── MongoDbUserPasswordStoreTests.cs
│ ├── MongoDbUserPhoneNumberStoreTests.cs
│ ├── MongoDbUserRoleStoreTests.cs
│ ├── MongoDbUserSecurityStampStoreTests.cs
│ ├── MongoDbUserStoreTests.cs
│ ├── MongoDbUserTwoFactorRecoveryCodeStoreTests.cs
│ ├── MongoDbUserTwoFactorStoreTests.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── _Comparers.cs
│ └── xunit.runner.json
└── Directory.Build.props
└── version.props
/.dockerignore:
--------------------------------------------------------------------------------
1 | .dockerignore
2 | .env
3 | .git
4 | .gitignore
5 | .vs
6 | .vscode
7 | docker-compose.yml
8 | docker-compose.*.yml
9 | */bin
10 | */obj
11 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | *.sh text eol=lf
3 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: csharp
2 | sudo: false
3 | dotnet: 2.1.2
4 | dist: trusty
5 | env:
6 | global:
7 | - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
8 | - DOTNET_CLI_TELEMETRY_OPTOUT: 1
9 | mono: none
10 | services:
11 | - mongodb
12 | os:
13 | - linux
14 | # - osx
15 | osx_image: xcode8.1
16 | addons:
17 | apt:
18 | packages:
19 | - libunwind8
20 | branches:
21 | only:
22 | - master
23 | - release
24 | - develop
25 | - /^rel\/.*/
26 | - /^(.*\/)?ci-.*$/
27 | script:
28 | - ./build.sh
--------------------------------------------------------------------------------
/Blueshift.EntityFrameworkCore.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | $([System.DateTime]::Now.ToString('yyyy'))
8 | git
9 | $(MSBuildThisFileDirectory)
10 | https://github.com/crhairr/EntityFrameworkCore.MongoDb.git
11 |
14 | True
15 | Blueshift Software, LLC
16 | $(Company)
17 | © $(Company) @ $(BuildYear) - all rights reserved.
18 | Blueshift;MongoDB;Entity Framework Core;entity-framework-core;EF;Data;O/RM
19 | Blueshift Software MongoDB Provider for Entity Framework Core
20 | full
21 | 7.2
22 | $(NoWarn);CS8032;
23 |
24 | $(MSBuildProjectName)
25 | $(MSBuildProjectName)
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MicrosoftNETCoreApp20PackageVersion)
5 | $(NETStandardLibrary20PackageVersion)
6 |
7 | 99.9
8 |
9 |
10 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017 Blueshift Software, LLC. All rights reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4 | these files except in compliance with the License. You may obtain a copy of the
5 | License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software distributed
10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
12 | specific language governing permissions and limitations under the License.
13 |
--------------------------------------------------------------------------------
/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This repository has been defunct for some time. Due to a lack of both public interest and general support from the Microsoft Entity Framework team, I have decided to formally end support for the solution and archive the repository.
2 |
3 |
4 | # Document Database Providers for Entity Framework Core
5 |
6 | Welcome to the home of Document Database (NoSQL) Providers for EntityFrameworkCore!
7 |
8 | [](https://ci.appveyor.com/project/crhairr/entityframeworkcore-mongodb/) [](https://travis-ci.org/BlueshiftSoftware/EntityFrameworkCore)
9 |
10 | This repository currently only contains a MongoDB provider for EF Core. However, there are plans in the current roadmap to expand this with further NoSQL provider offerings.
11 |
12 | MongoDb is a highly popular No-SQL database solution for storing structured, non-relational document data. This provider enables applications built with EntityFrameworkCore to use MongoDb instances as a backing data store.
13 |
14 | Find out how to get started by visiting the [Wiki pages](https://github.com/crhairr/EntityFrameworkCore.MongoDb/wiki). Feel free to contribute to this repository with code, comments, wiki entries, and/or issues.
15 |
16 | The latest release and CI previews builds are available at the EntityFrameworkCore.MongoDb [MyGet Feed](https://www.myget.org/gallery/efcore-mongodb/).
17 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | init:
2 | - git config --global core.autocrlf true
3 | clone_depth: 1
4 | test: off
5 | services:
6 | - mongodb
7 | environment:
8 | global:
9 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
10 | DOTNET_CLI_TELEMETRY_OPTOUT: 1
11 | matrix:
12 | fast_finish: true
13 | for:
14 | -
15 | matrix:
16 | only:
17 | - image: Ubuntu
18 | build_script:
19 | - sh: chmod +x ./run.sh
20 | - sh: ./run.sh default-build
21 | -
22 | matrix:
23 | only:
24 | - image: Visual Studio 2017
25 | build_script:
26 | - ps: .\run.ps1 default-build
27 | artifacts:
28 | - path: 'artifacts\build\*.nupkg'
29 | name: MyGet
30 | deploy:
31 | - provider: Environment
32 | name: MyGet
33 | artifact: 'artifacts\build\*.nupkg'
34 | on:
35 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
36 | image:
37 | - Ubuntu
38 | - Visual Studio 2017
39 |
--------------------------------------------------------------------------------
/build.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE"
3 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -euo pipefail
4 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
5 |
6 | # Call "sync" between "chmod" and execution to prevent "text file busy" error in Docker (aufs)
7 | chmod +x "$DIR/run.sh"; sync
8 | "$DIR/run.sh" default-build "$@"
9 |
--------------------------------------------------------------------------------
/build/dependencies.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
5 |
6 |
7 |
8 | 2.1.1
9 | 2.0.3
10 |
11 |
12 |
13 | 2.1.3
14 | 2.1.2
15 | 2.1.2
16 | 2.1.1
17 |
18 |
19 |
20 | 2.7.3
21 |
22 |
23 |
24 | 15.9.0
25 | 4.10.1
26 | 2.4.1
27 | 2.4.1
28 | 2.4.1
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/build/repo.beforecommon.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 |
6 |
--------------------------------------------------------------------------------
/build/repo.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | False
5 |
6 | true
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/build/repo.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/build/sources.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $(DotNetRestoreSources)
6 |
7 | $(RestoreSources);
8 | https://dotnet.myget.org/F/dotnet-core/api/v3/index.json;
9 | https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
10 | https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
11 | https://www.myget.org/F/efcore-mongodb/api/v3/index.json;
12 |
13 |
14 | $(RestoreSources);
15 | https://api.nuget.org/v3/index.json;
16 |
17 |
18 |
--------------------------------------------------------------------------------
/docker-compose.dcproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2.1
4 | Linux
5 | 04ceb217-71e2-4dbd-b35a-737ee7d258b8
6 | LaunchBrowser
7 | {Scheme}://localhost:{ServicePort}
8 | blueshift.authoring
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.4'
2 |
3 | services:
4 | mongo-efcore:
5 | image: mongo:4.1.2-xenial
6 | restart: always
7 | ports:
8 | - 27017:27017
9 | mongo-efcore-express:
10 | image: mongo-express
11 | restart: always
12 | ports:
13 | - 27027:8081
14 | environment:
15 | ME_CONFIG_MONGODB_SERVER: mongo-efcore
16 |
--------------------------------------------------------------------------------
/korebuild-lock.txt:
--------------------------------------------------------------------------------
1 | version:2.1.3-rtm-15802
2 | commithash:a7c08b45b440a7d2058a0aa1eaa3eb6ba811976a
--------------------------------------------------------------------------------
/korebuild.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.1/tools/korebuild.schema.json",
3 | "channel": "release/2.1"
4 | }
--------------------------------------------------------------------------------
/run.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE"
3 |
--------------------------------------------------------------------------------
/src/Blueshift.EntityFrameworkCore.MongoDB.SampleDomain/Blueshift.EntityFrameworkCore.MongoDB.SampleDomain.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(BuildFrameworks)
5 | Blueshift MongoDb Provider for EntityFrameworkCore
6 | Sample Domain Library for EntityFramework Core MongoDb Provider
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/Blueshift.EntityFrameworkCore.MongoDB.SampleDomain/ZooDbDependencyInjection.cs:
--------------------------------------------------------------------------------
1 | using Blueshift.EntityFrameworkCore.MongoDB.Infrastructure;
2 | using Microsoft.Extensions.DependencyInjection;
3 |
4 | namespace Blueshift.EntityFrameworkCore.MongoDB.SampleDomain
5 | {
6 | public static class ZooDbDependencyInjection
7 | {
8 | public static IServiceCollection AddZooDbContext(this IServiceCollection serviceCollection)
9 | {
10 | return serviceCollection
11 | .AddDbContext(options => options.UseMongoDb("mongodb://localhost"));
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Blueshift.EntityFrameworkCore.MongoDB/Adapter/Conventions/AbstractBaseClassConvention.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.EntityFrameworkCore.Utilities;
2 | using MongoDB.Bson.Serialization;
3 | using MongoDB.Bson.Serialization.Attributes;
4 | using MongoDB.Bson.Serialization.Conventions;
5 |
6 | namespace Blueshift.EntityFrameworkCore.MongoDB.Adapter.Conventions
7 | {
8 | ///
9 | ///
10 | ///
11 | /// A convention that specifies that a discriminator is required when the given type is abstract.
12 | ///
13 | public class AbstractBaseClassConvention : BsonClassMapAttributeConvention
14 | {
15 | ///
16 | ///
17 | /// Process the conventions on according to the given .
18 | ///
19 | /// The to which the conventions will be assigned.
20 | /// The that defines the convention.
21 | protected override void Apply(BsonClassMap classMap, BsonKnownTypesAttribute attribute)
22 | {
23 | Check.NotNull(classMap, nameof(classMap));
24 | if (!classMap.DiscriminatorIsRequired)
25 | {
26 | classMap.SetDiscriminatorIsRequired(classMap.ClassType.IsAbstract);
27 | }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/src/Blueshift.EntityFrameworkCore.MongoDB/Adapter/Conventions/BsonClassMapAttributeConvention.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using System.Text.RegularExpressions;
5 | using JetBrains.Annotations;
6 | using Microsoft.EntityFrameworkCore.Utilities;
7 | using MongoDB.Bson.Serialization;
8 | using MongoDB.Bson.Serialization.Conventions;
9 |
10 | namespace Blueshift.EntityFrameworkCore.MongoDB.Adapter.Conventions
11 | {
12 | ///
13 | ///
14 | ///
15 | /// Base class for attribute-based convention processing.
16 | ///
17 | /// The type of attribute to process.
18 | public abstract class BsonClassMapAttributeConvention : ConventionBase, IClassMapConvention
19 | where TAttribute : Attribute
20 | {
21 | ///
22 | ///
23 | /// Initializes a new instance of the .
24 | ///
25 | protected BsonClassMapAttributeConvention()
26 | : base(Regex.Replace(typeof(TAttribute).Name, "Attribute$", ""))
27 | {
28 | }
29 |
30 |
31 | ///
32 | ///
33 | /// Processes each defined on the given
34 | /// member info and
35 | ///
36 | /// The to
37 | public virtual void Apply(BsonClassMap classMap)
38 | {
39 | Check.NotNull(classMap, nameof(classMap));
40 | IEnumerable memberMapAttributes = classMap
41 | .ClassType
42 | .GetCustomAttributes();
43 | foreach (TAttribute attribute in memberMapAttributes)
44 | {
45 | Apply(classMap, attribute);
46 | }
47 | }
48 |
49 | ///
50 | /// Process the conventions on according to the given .
51 | ///
52 | /// The to which the conventions will be assigned.
53 | /// The that defines the convention.
54 | protected abstract void Apply([NotNull] BsonClassMap classMap, [NotNull] TAttribute attribute);
55 | }
56 | }
--------------------------------------------------------------------------------
/src/Blueshift.EntityFrameworkCore.MongoDB/Adapter/Conventions/BsonMemberMapAttributeConvention.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using System.Text.RegularExpressions;
5 | using JetBrains.Annotations;
6 | using Microsoft.EntityFrameworkCore.Utilities;
7 | using MongoDB.Bson.Serialization;
8 | using MongoDB.Bson.Serialization.Conventions;
9 |
10 | namespace Blueshift.EntityFrameworkCore.MongoDB.Adapter.Conventions
11 | {
12 | ///
13 | /// Base class for attribute-based convention processing.
14 | ///
15 | /// The type of attribute to process.
16 | public abstract class BsonMemberMapAttributeConvention : ConventionBase, IMemberMapConvention
17 | where TAttribute : Attribute
18 | {
19 | ///
20 | /// Initializes a new instance of the .
21 | ///
22 | protected BsonMemberMapAttributeConvention()
23 | : base(Regex.Replace(typeof(TAttribute).Name, "Attribute$", ""))
24 | {
25 | }
26 |
27 | ///
28 | /// Processes each defined on the given
29 | /// member info and
30 | ///
31 | /// The to
32 | public virtual void Apply([NotNull] BsonMemberMap memberMap)
33 | {
34 | Check.NotNull(memberMap, nameof(memberMap));
35 | IEnumerable memberMapAttributes = memberMap.MemberInfo
36 | .GetCustomAttributes();
37 | foreach (TAttribute attribute in memberMapAttributes)
38 | {
39 | Apply(memberMap, attribute);
40 | }
41 | }
42 |
43 | ///
44 | /// Process the conventions on according to the given .
45 | ///
46 | /// The to which the conventions will be assigned.
47 | /// The that defines the convention.
48 | protected abstract void Apply([NotNull] BsonMemberMap memberMap, [NotNull] TAttribute attribute);
49 | }
50 | }
--------------------------------------------------------------------------------
/src/Blueshift.EntityFrameworkCore.MongoDB/Adapter/Conventions/IgnoreEmptyEnumerablesConvention.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Text.RegularExpressions;
4 | using JetBrains.Annotations;
5 | using Microsoft.EntityFrameworkCore.Utilities;
6 | using MongoDB.Bson.Serialization;
7 | using MongoDB.Bson.Serialization.Conventions;
8 |
9 | namespace Blueshift.EntityFrameworkCore.MongoDB.Adapter.Conventions
10 | {
11 | ///
12 | /// A convention that ignores empty instances when serializing Bson documents.
13 | ///
14 | public class IgnoreEmptyEnumerablesConvention : ConventionBase, IMemberMapConvention
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | public IgnoreEmptyEnumerablesConvention()
20 | : base(Regex.Replace(nameof(IgnoreEmptyEnumerablesConvention), "Convention$", ""))
21 | {
22 | }
23 |
24 | ///
25 | /// Applies the Ignore Empty Enumerables convention to the given .
26 | ///
27 | /// The to which the convention will be applied.
28 | public virtual void Apply([NotNull] BsonMemberMap memberMap)
29 | {
30 | Check.NotNull(memberMap, nameof(memberMap));
31 | if (memberMap.MemberType.TryGetSequenceType() != null)
32 | {
33 | memberMap.SetShouldSerializeMethod(@object =>
34 | {
35 | object value = memberMap.Getter(@object);
36 | return (value as IEnumerable)?.GetEnumerator().MoveNext() ?? false;
37 | });
38 | }
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Blueshift.EntityFrameworkCore.MongoDB/Adapter/Conventions/IgnoreNullOrEmptyStringsConvention.cs:
--------------------------------------------------------------------------------
1 | using System.Text.RegularExpressions;
2 | using JetBrains.Annotations;
3 | using Microsoft.EntityFrameworkCore.Utilities;
4 | using MongoDB.Bson.Serialization;
5 | using MongoDB.Bson.Serialization.Conventions;
6 |
7 | namespace Blueshift.EntityFrameworkCore.MongoDB.Adapter.Conventions
8 | {
9 | ///
10 | /// Instructs the MongoDb C# driver to ignore null, empty, or default values of properties.
11 | ///
12 | public class IgnoreNullOrEmptyStringsConvention : ConventionBase, IMemberMapConvention
13 | {
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | public IgnoreNullOrEmptyStringsConvention()
18 | : base(Regex.Replace(nameof(IgnoreNullOrEmptyStringsConvention), "Convention$", ""))
19 | {
20 | }
21 |
22 | ///
23 | /// Applies the Ignore Null or Empty Strings convention to the given .
24 | ///
25 | /// The to which the convention will be applied.
26 | public virtual void Apply([NotNull] BsonMemberMap memberMap)
27 | {
28 | Check.NotNull(memberMap, nameof(memberMap));
29 | if (memberMap.MemberType == typeof(string))
30 | {
31 | SetShouldSerializeMethod(memberMap);
32 | }
33 | }
34 |
35 | private static void SetShouldSerializeMethod(BsonMemberMap memberMap)
36 | {
37 | var defaultString = memberMap.DefaultValue as string;
38 | if (!string.IsNullOrEmpty(defaultString))
39 | {
40 | ShouldSerializeIfNotDefault(memberMap, defaultString);
41 | }
42 | else
43 | {
44 | ShouldSerializeIfNotEmpty(memberMap);
45 | }
46 | }
47 |
48 | private static void ShouldSerializeIfNotEmpty(BsonMemberMap memberMap)
49 | => memberMap.SetShouldSerializeMethod(@object => !string.IsNullOrEmpty(memberMap.Getter(@object) as string));
50 |
51 | private static void ShouldSerializeIfNotDefault(BsonMemberMap memberMap, string defaultString)
52 | => memberMap.SetShouldSerializeMethod(@object => !string.Equals(defaultString, memberMap.Getter(@object) as string));
53 | }
54 | }
--------------------------------------------------------------------------------
/src/Blueshift.EntityFrameworkCore.MongoDB/Adapter/Conventions/KeyAttributeConvention.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 | using Microsoft.EntityFrameworkCore.Utilities;
3 | using MongoDB.Bson.Serialization;
4 |
5 | namespace Blueshift.EntityFrameworkCore.MongoDB.Adapter.Conventions
6 | {
7 | ///
8 | /// A convention that sets the of a
9 | /// if that property has been decorated with a .
10 | ///
11 | public class KeyAttributeConvention : BsonMemberMapAttributeConvention
12 | {
13 | ///
14 | /// Applies the Key Attribute convention to the given .
15 | ///
16 | /// The to which the convention will be applied.
17 | /// The to apply.
18 | protected override void Apply(BsonMemberMap memberMap, KeyAttribute attribute)
19 | => Check.NotNull(memberMap, nameof(memberMap))
20 | .ClassMap
21 | .SetIdMember(memberMap);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Blueshift.EntityFrameworkCore.MongoDB/Adapter/Conventions/NavigationSrializationMemberMapConvention.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel.DataAnnotations;
3 | using System.Linq;
4 | using System.Reflection;
5 | using Blueshift.EntityFrameworkCore.MongoDB.Adapter.Serialization;
6 | using Microsoft.EntityFrameworkCore.Utilities;
7 | using MongoDB.Bson.Serialization;
8 | using MongoDB.Bson.Serialization.Attributes;
9 | using MongoDB.Bson.Serialization.Conventions;
10 |
11 | namespace Blueshift.EntityFrameworkCore.MongoDB.Adapter.Conventions
12 | {
13 | ///
14 | ///
15 | ///
16 | /// A convention for specifying how to serialize navigation properties.
17 | ///
18 | public class NavigationSrializationMemberMapConvention : ConventionBase, IMemberMapConvention
19 | {
20 | ///
21 | ///
22 | /// Checks whether the member map represents a navigation, and sets the member map's serializer.
23 | ///
24 | /// The member map.
25 | public void Apply(BsonMemberMap memberMap)
26 | {
27 | Type memberTargetType = Check.NotNull(memberMap, nameof(memberMap)).MemberType.TryGetSequenceType()
28 | ?? memberMap.MemberType;
29 | if (!memberTargetType.IsPrimitive && HasIdMember(memberTargetType))
30 | {
31 | IBsonSerializer memberMapSerializer = (IBsonSerializer) Activator.CreateInstance(
32 | typeof(NavigationBsonMemberMapSerializer<>).MakeGenericType(memberTargetType),
33 | memberMap);
34 | memberMap.SetSerializer(memberMapSerializer);
35 | }
36 | }
37 |
38 | private bool HasIdMember(Type type)
39 | => !type.IsPrimitive
40 | && type
41 | .GetMembers(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance)
42 | .Any(memberInfo => memberInfo.IsDefined(typeof(BsonIdAttribute))
43 | || memberInfo.IsDefined(typeof(KeyAttribute)));
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Blueshift.EntityFrameworkCore.MongoDB/Adapter/Conventions/NotMappedAttributeConvention.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations.Schema;
2 | using Microsoft.EntityFrameworkCore.Utilities;
3 | using MongoDB.Bson.Serialization;
4 |
5 | namespace Blueshift.EntityFrameworkCore.MongoDB.Adapter.Conventions
6 | {
7 | ///
8 | /// Marks a as ignored during serialization.
9 | ///
10 | public class NotMappedAttributeConvention : BsonMemberMapAttributeConvention
11 | {
12 | ///
13 | /// Applies the Not Mapped convention to the given .
14 | ///
15 | /// The to which the convention will be applied.
16 | /// The to apply.
17 | protected override void Apply(BsonMemberMap memberMap, NotMappedAttribute attribute)
18 | => Check.NotNull(memberMap, nameof(memberMap))
19 | .ClassMap
20 | .UnmapMember(memberMap.MemberInfo);
21 | }
22 | }
--------------------------------------------------------------------------------
/src/Blueshift.EntityFrameworkCore.MongoDB/Adapter/EntityFrameworkConventionPack.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Blueshift.EntityFrameworkCore.MongoDB.Adapter.Conventions;
3 | using MongoDB.Bson.Serialization.Conventions;
4 |
5 | namespace Blueshift.EntityFrameworkCore.MongoDB.Adapter
6 | {
7 | ///
8 | ///
9 | /// Provides a set of conventions that configures the MongoDb C# Driver to work appropriately with the EntityFrameworkCore.
10 | ///
11 | public class EntityFrameworkConventionPack : ConventionPack
12 | {
13 | ///
14 | /// Registers the .
15 | ///
16 | ///
17 | public static void Register(Func typeFilter)
18 | {
19 | ConventionRegistry.Register(
20 | "Blueshift.EntityFrameworkCore.MongoDb.Conventions",
21 | Instance,
22 | typeFilter);
23 | }
24 |
25 | ///
26 | /// The singleton instance of .
27 | ///
28 | public static EntityFrameworkConventionPack Instance { get; } = new EntityFrameworkConventionPack();
29 |
30 | private EntityFrameworkConventionPack()
31 | {
32 | AddRange(new IConvention[]
33 | {
34 | new AbstractBaseClassConvention(),
35 | new KeyAttributeConvention(),
36 | new NavigationSrializationMemberMapConvention(),
37 | new NotMappedAttributeConvention()
38 | });
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Blueshift.EntityFrameworkCore.MongoDB/Adapter/Serialization/BsonSerializerExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using JetBrains.Annotations;
5 | using Microsoft.EntityFrameworkCore.Utilities;
6 | using MongoDB.Bson.Serialization;
7 | using MongoDB.Bson.Serialization.Serializers;
8 |
9 | // ReSharper disable once CheckNamespace
10 | namespace Blueshift.EntityFrameworkCore.MongoDB.Adapter.Serialization
11 | {
12 | ///
13 | /// Provides extended functionality to .
14 | ///
15 | public static class BsonSerializerExtensions
16 | {
17 | ///
18 | /// Modifies an instance of to only use the supplied members when serializing instances.
19 | ///
20 | /// The to modify.
21 | /// An of that lists the members
22 | /// required for serialization.
23 | /// A new instance of that serializes the information in .
24 | public static IBsonSerializer AsDenormalizingBsonClassMapSerializer(
25 | [NotNull] this IBsonSerializer bsonSerializer,
26 | [CanBeNull] IEnumerable denormalizedMemberNames = null)
27 | {
28 | TypeInfo typeInfo = Check.NotNull(bsonSerializer, nameof(bsonSerializer)).GetType().GetTypeInfo();
29 |
30 | if (bsonSerializer is IChildSerializerConfigurable childSerializerConfigurable)
31 | {
32 | bsonSerializer = childSerializerConfigurable.WithChildSerializer(
33 | childSerializerConfigurable.ChildSerializer.AsDenormalizingBsonClassMapSerializer(denormalizedMemberNames));
34 | }
35 | else if (typeInfo.TryGetImplementationType(typeof(ReadOnlyCollectionSerializer<>),
36 | out Type readOnlyCollectionSerializerType)
37 | || typeInfo.TryGetImplementationType(typeof(ReadOnlyCollectionSubclassSerializer<,>),
38 | out readOnlyCollectionSerializerType))
39 | {
40 | bsonSerializer = (IBsonSerializer) Activator.CreateInstance(readOnlyCollectionSerializerType,
41 | ((IBsonSerializer) readOnlyCollectionSerializerType
42 | .GetProperty(nameof(EnumerableSerializerBase