├── .editorconfig ├── .gitignore ├── BREAKING-CHANGES.md ├── CODEOWNERS ├── CONTRIBUTING.md ├── LICENSE.md ├── MongoDB.EFCoreProvider.sln ├── MongoDB.EFCoreProvider.sln.DotSettings ├── README.md ├── THIRD-PARTY-NOTICES ├── apidocs ├── .gitignore ├── api │ ├── MongoDB.md │ └── index.md ├── docfx.json ├── images │ └── mongodb-logo.svg ├── index.md └── mongo-apidocs │ └── public │ └── main.css ├── evergreen ├── build-apidocs.sh ├── download-augmented-sbom.sh ├── evergreen.yml ├── generate-ssdlc-report.sh ├── generate-version.sh ├── install-dependencies.sh ├── pack-packages.sh ├── push-packages.sh ├── run-smoke-tests.sh ├── run-tests.sh ├── sign-packages.sh ├── template_ssdlc_compliance_report.md └── upload-apidocs.sh ├── global.json ├── nuget.config ├── packageIcon.png ├── sbom.json ├── src ├── Directory.Build.props └── MongoDB.EntityFrameworkCore │ ├── ChangeTracking │ ├── ListOfNullableValueTypesComparer.cs │ ├── ListOfReferenceTypesComparer.cs │ ├── ListOfValueTypesComparer.cs │ ├── NullableEqualityComparer.cs │ ├── NullableStringDictionaryComparer.cs │ └── StringDictionaryComparer.cs │ ├── Design │ └── MongoDesignTimeServices.cs │ ├── Diagnostics │ ├── MongoBulkWriteEventData.cs │ ├── MongoEventId.cs │ ├── MongoLoggerExtensions.cs │ ├── MongoLoggerTransactionExtensions.cs │ ├── MongoLoggerUpdateExtensions.cs │ ├── MongoLoggingDefinitions.cs │ ├── MongoQueryEventData.cs │ ├── MongoTransactionEndEventData.cs │ ├── MongoTransactionErrorEventData.cs │ ├── MongoTransactionEventData.cs │ ├── MongoTransactionStartingEventData.cs │ └── NonCapturingLazyInitializer.cs │ ├── EnumerableMethods.cs │ ├── ExceptionHelpers.cs │ ├── ExpressionExtensionMethods.cs │ ├── Extensions │ ├── MongoDbContextOptionsExtensions.cs │ ├── MongoEntityTypeBuilderExtensions.cs │ ├── MongoEntityTypeExtensions.cs │ ├── MongoIndexBuilderExtensions.cs │ ├── MongoIndexExtensions.cs │ ├── MongoNavigationExtensions.cs │ ├── MongoPropertiesConfigurationBuilderExtensions.cs │ ├── MongoPropertyBuilderExtensions.cs │ ├── MongoPropertyExtensions.cs │ └── MongoServiceCollectionExtensions.cs │ ├── Infrastructure │ ├── IMongoDbContextOptionsBuilderInfrastructure.cs │ ├── MongoDbContextOptionsBuilder.cs │ ├── MongoModelRuntimeInitializer.cs │ ├── MongoModelValidator.cs │ └── MongoOptionsExtension.cs │ ├── Metadata │ ├── Attributes │ │ └── CollectionAttribute.cs │ ├── BsonRepresentationConfiguration.cs │ ├── Conventions │ │ ├── BsonAttributes │ │ │ ├── BsonDateTimeOptionsAttributeConvention.cs │ │ │ ├── BsonDefaultValueAttributeConvention.cs │ │ │ ├── BsonDictionaryOptionsAttributeConvention.cs │ │ │ ├── BsonElementAttributeConvention.cs │ │ │ ├── BsonExtraElementsAttributeConvention.cs │ │ │ ├── BsonGuidRepresentationAttributeConvention.cs │ │ │ ├── BsonIdAttributeConvention.cs │ │ │ ├── BsonIgnoreAttributeConvention.cs │ │ │ ├── BsonIgnoreIfDefaultAttributeConvention.cs │ │ │ ├── BsonIgnoreIfNullAttributeConvention.cs │ │ │ ├── BsonRepresentationAttributeConvention.cs │ │ │ ├── BsonRequiredAttributeConvention.cs │ │ │ ├── BsonSerializationOptionsAttributeConvention.cs │ │ │ ├── BsonSerializerPropertyConvention.cs │ │ │ └── BsonTimeSpanOptionsAttributeConvention.cs │ │ ├── CamelCaseElementNameConvention.cs │ │ ├── CollectionAttributeConvention.cs │ │ ├── CollectionNameFromDbSetConvention.cs │ │ ├── ColumnAttributeConvention.cs │ │ ├── DateTimeKindConvention.cs │ │ ├── MongoConventionSetBuilder.cs │ │ ├── MongoRelationshipDiscoveryConvention.cs │ │ ├── MongoValueGenerationConvention.cs │ │ ├── NotSupportedPropertyAttributeConvention.cs │ │ ├── PrimaryKeyDiscoveryConvention.cs │ │ └── TableAttributeConvention.cs │ └── MongoAnnotationNames.cs │ ├── MongoDB.EntityFrameworkCore.csproj │ ├── NamingHelperMethods.cs │ ├── Query │ ├── Expressions │ │ ├── CollectionShaperExpression.cs │ │ ├── EntityProjectionExpression.cs │ │ ├── EntityTypedExpression.cs │ │ ├── IAccessExpression.cs │ │ ├── MongoCollectionExpression.cs │ │ ├── MongoQueryExpression.cs │ │ ├── ObjectAccessExpression.cs │ │ ├── ObjectArrayProjectionExpression.cs │ │ ├── ProjectionExpression.cs │ │ └── RootReferenceExpression.cs │ ├── Factories │ │ ├── MongoQueryCompilationContextFactory.cs │ │ ├── MongoQueryContextFactory.cs │ │ ├── MongoQueryTranslationPostprocessorFactory.cs │ │ ├── MongoQueryTranslationPreprocessorFactory.cs │ │ ├── MongoQueryableMethodTranslatingExpressionVisitorFactory.cs │ │ └── MongoShapedQueryCompilingExpressionVisitorFactory.cs │ ├── MongoExecutableQuery.cs │ ├── MongoQueryCompilationContext.cs │ ├── MongoQueryContext.cs │ ├── MongoQueryTranslationPostprocessor.cs │ ├── MongoQueryTranslationPreprocessor.cs │ ├── QueryingEnumerable.cs │ └── Visitors │ │ ├── BsonDocumentInjectingExpressionVisitor.cs │ │ ├── Dependencies │ │ └── MongoShapedQueryCompilingExpressionVisitorDependencies.cs │ │ ├── EntityFrameworkDetourExpressionVisitor.cs │ │ ├── FinalPredicateHoistingVisitor.cs │ │ ├── MongoEFToLinqTranslatingExpressionVisitor.cs │ │ ├── MongoProjectionBindingExpressionVisitor.cs │ │ ├── MongoProjectionBindingRemovingExpressionVisitor.cs │ │ ├── MongoQueryableMethodTranslatingExpressionVisitor.cs │ │ ├── MongoShapedQueryCompilingExpressionVisitor.cs │ │ └── ProjectionBindingRemovingExpressionVisitor.cs │ ├── Serializers │ ├── BsonSerializerFactory.cs │ ├── EntitySerializer.cs │ ├── MongoEFDiscriminator.cs │ └── ValueConverterSerializer.cs │ ├── Storage │ ├── BsonBinding.cs │ ├── IMongoClientWrapper.cs │ ├── MongoClientWrapper.cs │ ├── MongoDatabaseCreator.cs │ ├── MongoDatabaseWrapper.cs │ ├── MongoTransaction.cs │ ├── MongoTransactionManager.cs │ ├── MongoTypeMapping.cs │ ├── MongoTypeMappingSource.cs │ ├── MongoUpdate.cs │ ├── MongoUpdateBatch.cs │ ├── RowVersion.cs │ └── ValueConversion │ │ ├── Decimal128DecimalConverter.cs │ │ ├── Decimal128ToDecimalConverter.cs │ │ ├── DecimalToDecimal128Converter.cs │ │ ├── MongoValueConverterSelector.cs │ │ ├── ObjectIdToStringConverter.cs │ │ ├── StringObjectIdConverter.cs │ │ └── StringToObjectIdConverter.cs │ ├── TypeExtensionMethods.cs │ └── ValueGeneration │ ├── MongoValueGeneratorSelector.cs │ ├── ObjectIdValueGenerator.cs │ └── StringObjectIdValueGenerator.cs └── tests ├── Directory.Build.props ├── MongoDB.EntityFrameworkCore.FunctionalTests ├── Compatibility │ ├── EncryptionTests.cs │ └── StoredDataStillReadableTests.cs ├── Design │ ├── CompiledModelTests.cs │ └── Generated │ │ ├── EF8 │ │ ├── EveryTypeEntityType.cs │ │ ├── OwnedEntityEntityType.cs │ │ ├── SimpleContextModel.cs │ │ └── SimpleContextModelBuilder.cs │ │ └── EF9 │ │ ├── EveryTypeEntityType.cs │ │ ├── OwnedEntityEntityType.cs │ │ ├── SimpleContextAssemblyAttributes.cs │ │ ├── SimpleContextModel.cs │ │ └── SimpleContextModelBuilder.cs ├── Entities │ └── Guides │ │ ├── GuidesDbContext.cs │ │ └── Planet.cs ├── Exerciser.cs ├── LoggingTests.cs ├── Mapping │ ├── BsonRepresentationTests.cs │ ├── ClrTypeMappingTests.cs │ ├── DiscriminatorTests.cs │ ├── ElementNameTests.cs │ ├── NavigationProxyTests.cs │ ├── ShadowPropertyTests.cs │ └── ValueConverterTests.cs ├── Metadata │ └── Conventions │ │ ├── BsonAttributes │ │ ├── BsonElementAttributeConventionTests.cs │ │ └── BsonIgnoreAttributeConventionTests.cs │ │ ├── CamelCaseElementNameConventionTests.cs │ │ ├── ColumnAttributeConventionTests.cs │ │ └── PrimaryKeyDiscoveryConventionTests.cs ├── MongoDB.EntityFrameworkCore.FunctionalTests.csproj ├── Query │ ├── CollectionsResponseTests.cs │ ├── CompositeKeyQueryTests.cs │ ├── FindTests.cs │ ├── FirstSingleTests.cs │ ├── GlobalQueryTests.cs │ ├── InvalidQueryTranslationTests.cs │ ├── MqlMethodTests.cs │ ├── OwnedEntityTests.cs │ ├── PrimitiveCollectionTests.cs │ ├── ProjectionTests.cs │ ├── SkipTakeOrderingTests.cs │ ├── TopScalarTests.cs │ ├── TopSetTests.cs │ ├── UnsupportedQueryTests.cs │ ├── WhereDictionaryTests.cs │ └── WhereTests.cs ├── Serialization │ ├── BaseSerializationTests.cs │ ├── BooleanSerializationTests.cs │ ├── ByteArraySerializationTests.cs │ ├── CollectionSerializationTests.cs │ ├── DateAndTimeSerializationTests.cs │ ├── DecimalSerializationTests.cs │ ├── DictionarySerializationTests.cs │ ├── FloatingSerializationTests.cs │ ├── GuidSerializationTests.cs │ ├── IntegerSerializationTests.cs │ ├── MongoTypeSerializationTests.cs │ ├── StringSerializationTests.cs │ └── UnsignedIntegerSerializationTests.cs ├── Storage │ ├── MongoClientWrapperTests.cs │ ├── MongoDatabaseCreatorTests.cs │ └── TransactionTests.cs ├── TestInitialization.cs ├── Update │ ├── AddEntityTests.cs │ ├── CompositeKeyCrudTests.cs │ ├── ConcurrencyCheckTests.cs │ ├── ContextTests.cs │ ├── DbContextPoolTests.cs │ ├── DeleteEntityTests.cs │ ├── OwnedNavigationPropertyCrudTests.cs │ ├── RowVersionTests.cs │ ├── SaveChangesTransactionTests.cs │ ├── SimpleKeyCrudTests.cs │ └── UpdateEntityTests.cs ├── Usings.cs ├── Utilities │ ├── EnumerableOnlyWrapper.cs │ ├── ExtensionMethods.cs │ ├── NamedContainer.cs │ ├── ReadOnlySampleGuidesFixture.cs │ ├── SampleGuides.cs │ ├── SampleGuidesFixture.cs │ ├── SingleEntityDbContext.cs │ ├── SpyLogging.cs │ ├── TemporaryDatabaseFixture.cs │ └── TestServer.cs └── ValueGeneration │ └── ValueGenerationTests.cs └── MongoDB.EntityFrameworkCore.UnitTests ├── Extensions ├── MongoDbContextOptionsExtensionsTest.cs ├── MongoPropertiesConfigurationBuilderExtensionsTests.cs └── MongoPropertyBuilderExtensionsTests.cs ├── Infrastructure ├── MongoModelValidatorTests.cs └── MongoOptionsExtensionTest.cs ├── Metadata ├── Attributes │ └── CollectionAttributeTests.cs ├── Conventions │ ├── BsonAttributes │ │ ├── BsonDateTimeOptionsAttributeConventionTests.cs │ │ ├── BsonElementAttributeConventionTests.cs │ │ ├── BsonIdAttributeConventionTests.cs │ │ ├── BsonIgnoreAttributeConventionTests.cs │ │ ├── BsonRepresentationAttributeConventionTests.cs │ │ ├── BsonRequiredAttributeConventionTests.cs │ │ └── BsonUnsupportedAttributesConventionTests.cs │ ├── CollectionAttributeConventionTests.cs │ ├── CollectionNameFromDbSetConventionTests.cs │ ├── ColumnAttributeConventionTests.cs │ ├── DateTimeKindConventionTests.cs │ ├── MongoConventionSetBuilderTest.cs │ ├── MongoValueGenerationConventionTests.cs │ ├── PrimaryKeyDiscoveryConventionTests.cs │ └── TableAttributeConventionTests.cs └── MongoBuilderExtensionTest.cs ├── MongoDB.EntityFrameworkCore.UnitTests.csproj ├── NamingHelperMethodTests.cs ├── Query └── Expressions │ ├── MongoCollectionExpressionTests.cs │ └── MongoQueryExpressionTests.cs ├── Storage ├── BsonBindingTests.cs └── MongoTransactionManagerTests.cs ├── TestUtilities ├── MongoTestHelpers.cs ├── SingleEntityDbContext.cs └── Utilities.cs ├── Usings.cs └── ValueGeneration ├── MongoValueGeneratorSelectorTests.cs ├── ObjectIdValueGeneratorTests.cs └── StringObjectIdValueGeneratorTests.cs /.gitignore: -------------------------------------------------------------------------------- 1 | # Visual Studio artifacts 2 | bin 3 | obj 4 | *.user 5 | *.suo 6 | *.vsp 7 | *.csproj.VisualState.xml 8 | *.vbproj.VisualState.xml 9 | *.cache 10 | TestResults 11 | .vs 12 | project.lock.json 13 | .vscode 14 | 15 | # JetBrains Rider artifacts 16 | .idea 17 | 18 | # CodeReview 19 | codereview.rc 20 | 21 | # GhostDoc artifacts 22 | CSharpDriver.sln.GhostDoc.xml 23 | 24 | # Mac OS artifacts 25 | .DS_Store 26 | 27 | # MonoDevelop artifacts 28 | *.pidb 29 | *.userprefs 30 | test-results 31 | 32 | # NUnit artifacts 33 | TestResult.xml 34 | 35 | # Resharper artifacts 36 | _ReSharper.* 37 | 38 | # Sandcastle artifacts 39 | Help 40 | *.shfbproj_* 41 | 42 | # Vim artifacts 43 | *.swp 44 | *~ 45 | 46 | # Nuget artifacts 47 | src/packages 48 | 49 | # Nupkg artifacts 50 | *.nupkg 51 | 52 | # NCrunch artifacts 53 | *.ncrunch* 54 | 55 | # Merge tool artifacts 56 | *.cs.orig 57 | *.vb.orig 58 | 59 | # Fake Artifacts 60 | .fake 61 | 62 | # Cake Artifacts 63 | .dotnet 64 | 65 | # Other 66 | .config 67 | artifacts 68 | packages 69 | /tools 70 | /evergreen/krb5.conf.empty 71 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Global owner for repo 2 | * @mongodb/dbx-csharp-dotnet 3 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing to the Mongo EF Core Provider 2 | 3 | ### Bugfixes 4 | 5 | - Before starting to write code, look for existing [tickets](https://jira.mongodb.org/browse/EF#selectedTab=com.atlassian.jira.plugin.system.project%3Asummary-panel) or create one for your specific issue. That way you avoid working on something that might not be of interest or that has been addressed already in a different branch. 6 | - Fork the [repo](https://github.com/mongodb/mongo-efcore-provider). 7 | - Ensure your core.autocrlf settings are set to true. 8 | - Follow the general coding style of the rest of the project. 9 | - Write tests and make sure they pass. 10 | - Your final commit should have the JIRA issue number as the first part of the commit message. 11 | - Submit a pull request from GitHub. 12 | -------------------------------------------------------------------------------- /MongoDB.EFCoreProvider.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | False 3 | DB -------------------------------------------------------------------------------- /apidocs/.gitignore: -------------------------------------------------------------------------------- 1 | .manifest 2 | api/**.yml 3 | -------------------------------------------------------------------------------- /apidocs/api/MongoDB.md: -------------------------------------------------------------------------------- 1 | --- 2 | redirect_url: ../index.html 3 | --- 4 | -------------------------------------------------------------------------------- /apidocs/api/index.md: -------------------------------------------------------------------------------- 1 | # MongoDB EF Core Provider API Reference -------------------------------------------------------------------------------- /apidocs/docfx.json: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": [ 3 | { 4 | "src": [ 5 | { 6 | "files": ["**/*.csproj"], 7 | "exclude": ["**/bin/**", "**/obj/**"], 8 | "src": "../src" 9 | } 10 | ], 11 | "dest": "api", 12 | "includePrivateMembers": false, 13 | "disableGitFeatures": false, 14 | "disableDefaultFilter": false, 15 | "noRestore": false, 16 | "namespaceLayout": "flattened", 17 | "memberLayout": "separatePages", 18 | "EnumSortOrder": "declaringOrder", 19 | "allowCompilationErrors": false 20 | } 21 | ], 22 | "build": { 23 | "content": [ 24 | { 25 | "files": ["api/**.yml", "api/index.md", "api/MongoDB.md"] 26 | }, 27 | { 28 | "files": ["*.md"] 29 | } 30 | ], 31 | "resource": [ 32 | { 33 | "files": ["images/**"] 34 | } 35 | ], 36 | "globalMetadataFiles": [], 37 | "fileMetadataFiles": [], 38 | "template": ["default", "modern", "mongo-apidocs"], 39 | "postProcessors": [], 40 | "keepFileLink": false, 41 | "disableGitFeatures": false, 42 | "globalMetadata": { 43 | "_appTitle": "MongoDB EF Core Provider API Reference", 44 | "_appFooter": "© 2023 MongoDB, Inc.", 45 | "_appLogoPath": "images/mongodb-logo.svg", 46 | "_disableContribution": "true" 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /apidocs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | redirect_url: api/index.html 3 | --- 4 | -------------------------------------------------------------------------------- /apidocs/mongo-apidocs/public/main.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --bs-font-sans-serif: 'Euclid Circular A','Helvetica Neue',Helvetica,Arial,sans-serif; 3 | --bs-font-monospace: "Source Code Pro", Menlo, monospace; 4 | } 5 | 6 | h1, h2, h3 { 7 | font-family: 'MongoDB Value Serif','Times New Roman',serif; 8 | color: rgb(0, 104, 74); 9 | font-weight: bold; 10 | } 11 | 12 | dt { 13 | font-weight: normal; 14 | } 15 | 16 | @font-face { 17 | font-family: Euclid Circular A; 18 | src: url(https://static.mongodb.com/com/fonts/EuclidCircularA-Regular-WebXL.woff2) format('woff2'); 19 | font-weight: normal; 20 | font-display: swap; 21 | } 22 | 23 | @font-face { 24 | font-family: Euclid Circular A; 25 | src: url(https://static.mongodb.com/com/fonts/EuclidCircularA-Medium-WebXL.woff2) format('woff2'); 26 | font-weight: 500; 27 | font-display: swap; 28 | } 29 | 30 | @font-face { 31 | font-family: MongoDB Value Serif; 32 | src: url(https://static.mongodb.com/com/fonts/MongoDBValueSerif-Regular.woff2) format('woff2'); 33 | font-weight: normal; 34 | font-display: swap; 35 | } 36 | 37 | @font-face { 38 | font-family: MongoDB Value Serif; 39 | src: url(https://static.mongodb.com/com/fonts/MongoDBValueSerif-Medium.woff2) format('woff2'); 40 | font-weight: 500; 41 | font-display: swap; 42 | } 43 | 44 | @font-face { 45 | font-family: MongoDB Value Serif; 46 | src: url(https://static.mongodb.com/com/fonts/MongoDBValueSerif-Bold.woff2) format('woff2'); 47 | font-weight: bold; 48 | font-display: swap; 49 | } 50 | 51 | @font-face { 52 | font-family: Source Code Pro; 53 | src: url(https://static.mongodb.com/com/fonts/SourceCodePro-Regular.ttf) format('truetype'); 54 | font-weight: normal; 55 | font-display: swap; 56 | } 57 | 58 | @font-face { 59 | font-family: Source Code Pro; 60 | src: url(https://static.mongodb.com/com/fonts/SourceCodePro-Medium.ttf) format('truetype'); 61 | font-weight: 500; 62 | font-display: swap; 63 | } 64 | -------------------------------------------------------------------------------- /evergreen/build-apidocs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o errexit # Exit the script with error if any of the commands fail 3 | 4 | if [ -z "$PACKAGE_VERSION" ]; then 5 | PACKAGE_VERSION=$(sh ./evergreen/generate-version.sh) 6 | echo Calculated PACKAGE_VERSION value: "$PACKAGE_VERSION" 7 | fi 8 | 9 | echo "Configure dotnet cli to use local manifest" 10 | dotnet new tool-manifest --force 11 | 12 | echo "Installing docfx tool" 13 | dotnet tool install docfx --version "2.76.0" --local --verbosity q 14 | 15 | echo "Building the api-docs" 16 | dotnet tool run docfx metadata ./apidocs/docfx.json --property ProduceReferenceAssembly=true 17 | dotnet tool run docfx build ./apidocs/docfx.json -o:./artifacts/apidocs/"$PACKAGE_VERSION" 18 | -------------------------------------------------------------------------------- /evergreen/download-augmented-sbom.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Environment variables used as input: 4 | # AWS_ACCESS_KEY_ID 5 | # AWS_SECRET_ACCESS_KEY 6 | # AWS_SESSION_TOKEN 7 | 8 | declare -r SSDLC_PATH="./artifacts/ssdlc" 9 | mkdir -p "${SSDLC_PATH}" 10 | 11 | echo "Downloading augmented sbom from Kondukto" 12 | 13 | # use AWS CLI to get the Kondukto API token from AWS Secrets Manager 14 | kondukto_token=$(aws secretsmanager get-secret-value --secret-id "kondukto-token" --region "us-east-1" --query 'SecretString' --output text) 15 | if [ $? -ne 0 ]; then 16 | exit 1 17 | fi 18 | # set the KONDUKTO_TOKEN environment variable 19 | echo "KONDUKTO_TOKEN=$kondukto_token" > ${PWD}/kondukto_credentials.env 20 | 21 | docker run --platform="linux/amd64" --rm -v ${PWD}:/pwd \ 22 | --env-file ${PWD}/kondukto_credentials.env \ 23 | artifactory.corp.mongodb.com/release-tools-container-registry-public-local/silkbomb:2.0 \ 24 | augment --repo mongodb/mongo-efcore-provider --branch main --sbom-in /pwd/sbom.json --sbom-out /pwd/${SSDLC_PATH}/augmented-sbom.json -------------------------------------------------------------------------------- /evergreen/generate-ssdlc-report.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o errexit # Exit the script with error if any of the commands fail 3 | 4 | # Environment variables used as input: 5 | # PRODUCT_NAME 6 | # PACKAGE_VERSION 7 | # task_id 8 | 9 | echo "$PRODUCT_NAME" 10 | echo "$PACKAGE_VERSION" 11 | echo "$github_commit" 12 | 13 | echo "Creating SSDLC reports" 14 | 15 | declare -r SSDLC_PATH="./artifacts/ssdlc" 16 | mkdir -p "${SSDLC_PATH}" 17 | 18 | echo "Creating SSDLC compliance report" 19 | declare -r TEMPLATE_SSDLC_REPORT_PATH="./evergreen/template_ssdlc_compliance_report.md" 20 | declare -r SSDLC_REPORT_PATH="${SSDLC_PATH}/ssdlc_compliance_report.md" 21 | cp "${TEMPLATE_SSDLC_REPORT_PATH}" "${SSDLC_REPORT_PATH}" 22 | 23 | declare -a SED_EDIT_IN_PLACE_OPTION 24 | if [[ "$OSTYPE" == "darwin"* ]]; then 25 | SED_EDIT_IN_PLACE_OPTION=(-i '') 26 | else 27 | SED_EDIT_IN_PLACE_OPTION=(-i) 28 | fi 29 | sed "${SED_EDIT_IN_PLACE_OPTION[@]}" \ 30 | -e "s/\${PRODUCT_NAME}/${PRODUCT_NAME}/g" \ 31 | -e "s/\${PACKAGE_VERSION}/$PACKAGE_VERSION/g" \ 32 | -e "s/\${task_id}/$task_id/g" \ 33 | -e "s/\${REPORT_DATE_UTC}/$(date -u +%Y-%m-%d)/g" \ 34 | -e "s/\${NUGET_SIGN_CERTIFICATE_FINGERPRINT}/${NUGET_SIGN_CERTIFICATE_FINGERPRINT}/g" \ 35 | "${SSDLC_REPORT_PATH}" 36 | ls "${SSDLC_REPORT_PATH}" 37 | -------------------------------------------------------------------------------- /evergreen/generate-version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o errexit # Exit the script with error if any of the commands fail 3 | 4 | if [ -n "$triggered_by_git_tag" ]; then 5 | PACKAGE_VERSION=$triggered_by_git_tag 6 | else 7 | PACKAGE_VERSION=$(git describe --tags) 8 | fi 9 | 10 | PACKAGE_VERSION=$(echo $PACKAGE_VERSION | cut -c 2-) 11 | echo "$PACKAGE_VERSION" 12 | -------------------------------------------------------------------------------- /evergreen/install-dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o errexit # Exit the script with error if any of the commands fail 3 | 4 | DOTNET_SDK_PATH=./.dotnet 5 | mkdir -p "$DOTNET_SDK_PATH" 6 | 7 | if [[ $OS =~ [Ww]indows.* ]]; then 8 | echo "Downloading Windows .NET SDK installer into $DOTNET_SDK_PATH folder..." 9 | curl -Lfo "$DOTNET_SDK_PATH"/dotnet-install.ps1 https://dot.net/v1/dotnet-install.ps1 10 | echo "Installing .NET 8.0 SDK..." 11 | powershell.exe "$DOTNET_SDK_PATH"/dotnet-install.ps1 -Channel 8.0 -InstallDir "$DOTNET_SDK_PATH" -NoPath 12 | else 13 | echo "Downloading .NET SDK installer into $DOTNET_SDK_PATH folder..." 14 | curl -Lfo "$DOTNET_SDK_PATH"/dotnet-install.sh https://dot.net/v1/dotnet-install.sh 15 | echo "Installing .NET 8.0 SDK..." 16 | bash "$DOTNET_SDK_PATH"/dotnet-install.sh --channel 8.0 --install-dir "$DOTNET_SDK_PATH" --no-path 17 | fi 18 | -------------------------------------------------------------------------------- /evergreen/pack-packages.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o errexit # Exit the script with error if any of the commands fail 3 | 4 | if [ -z "$PACKAGE_VERSION" ]; then 5 | PACKAGE_VERSION=$(sh ./evergreen/generate-version.sh) 6 | echo Calculated PACKAGE_VERSION value: "$PACKAGE_VERSION" 7 | fi 8 | 9 | BUILD_CONFIGURATION="Release" 10 | if [[ "${PACKAGE_VERSION}" == "9."* ]]; then 11 | BUILD_CONFIGURATION="Release EF9" 12 | fi 13 | 14 | echo Creating nuget package $PACKAGE_VERSION using $BUILD_CONFIGURATION build configuration... 15 | 16 | dotnet clean ./MongoDB.EFCoreProvider.sln 17 | dotnet pack ./MongoDB.EFCoreProvider.sln -o ./artifacts/nuget -c "$BUILD_CONFIGURATION" -p:Version="$PACKAGE_VERSION" --include-symbols -p:SymbolPackageFormat=snupkg -p:ContinuousIntegrationBuild=true 18 | -------------------------------------------------------------------------------- /evergreen/push-packages.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o errexit # Exit the script with error if any of the commands fail 3 | set +o xtrace # Disable tracing. 4 | 5 | # querying nuget source to find search base url 6 | packages_search_url=$(curl -X GET -s "${PACKAGES_SOURCE}" | jq -r 'first(.resources[] | select(."@type"=="SearchQueryService") | ."@id")') 7 | 8 | wait_until_package_is_available () 9 | { 10 | package=$1 11 | version=$2 12 | resp="" 13 | count=0 14 | echo "Checking package availability: ${package}:${version} at ${packages_search_url}" 15 | while [ -z "$resp" ] && [ $count -le 40 ]; do 16 | resp=$(curl -X GET -s "$packages_search_url?prerelease=true&take=1&q=PackageId:$package" | jq --arg jq_version "$version" '.data[0].versions[] | select(.version==$jq_version) | .version') 17 | if [ -z "$resp" ]; then 18 | echo "sleeping for 15 seconds..." 19 | sleep 15 20 | fi 21 | done 22 | 23 | if [ -z "$resp" ]; then 24 | echo "Timeout while waiting for package availability: ${package}" 25 | exit 1 26 | else 27 | echo "Package ${package} is available, version: ${resp}" 28 | fi 29 | } 30 | 31 | if [ -z "$PACKAGES_SOURCE" ]; then 32 | echo "PACKAGES_SOURCE variable should be set" 33 | exit 1 34 | fi 35 | 36 | if [ -z "$PACKAGES_SOURCE_KEY" ]; then 37 | echo "PACKAGES_SOURCE_KEY variable should be set" 38 | exit 1 39 | fi 40 | 41 | if [ -z "$PACKAGE_VERSION" ]; then 42 | echo "PACKAGE_VERSION variable should be set" 43 | exit 1 44 | fi 45 | 46 | if [ -z "$NUGET_SIGN_CERTIFICATE_FINGERPRINT" ]; then 47 | echo "NUGET_SIGN_CERTIFICATE_FINGERPRINT variable should be set" 48 | exit 1 49 | fi 50 | 51 | dotnet nuget verify ./artifacts/nuget/MongoDB.EntityFrameworkCore."$PACKAGE_VERSION".nupkg --certificate-fingerprint "$NUGET_SIGN_CERTIFICATE_FINGERPRINT" 52 | dotnet nuget push --source "$PACKAGES_SOURCE" --api-key "$PACKAGES_SOURCE_KEY" ./artifacts/nuget/MongoDB.EntityFrameworkCore."$PACKAGE_VERSION".nupkg 53 | 54 | wait_until_package_is_available "MongoDB.EntityFrameworkCore" "$PACKAGE_VERSION" 55 | -------------------------------------------------------------------------------- /evergreen/run-smoke-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o errexit # Exit the script with error if any of the commands fail 3 | 4 | MONGODB_URI=${MONGODB_URI:=mongodb://localhost:27017/} 5 | 6 | EFCORE_PROVIDER_PROJECT="./src/MongoDB.EntityFrameworkCore/MongoDB.EntityFrameworkCore.csproj" 7 | TESTS_PROJECT="./tests/MongoDB.EntityFrameworkCore.FunctionalTests/MongoDB.EntityFrameworkCore.FunctionalTests.csproj" 8 | 9 | BUILD_CONFIGURATION="Debug" 10 | if [[ "${PACKAGE_VERSION}" == "9."* ]]; then 11 | BUILD_CONFIGURATION="Debug EF9" 12 | fi 13 | 14 | echo Retargeting API tests to use generated package instead of project dependency... 15 | dotnet nuget add source "./artifacts/nuget" -n local --configfile "./nuget.config" 16 | dotnet nuget locals temp -c 17 | dotnet clean "./MongoDB.EFCoreProvider.sln" 18 | 19 | echo "Configuring test project: $TESTS_PROJECT" 20 | dotnet remove "$TESTS_PROJECT" reference "$EFCORE_PROVIDER_PROJECT" 21 | dotnet add "$TESTS_PROJECT" package "MongoDB.EntityFrameworkCore" -v "$PACKAGE_VERSION" 22 | 23 | echo "Run tests: $TESTS_PROJECT" 24 | dotnet test "$TESTS_PROJECT" -c "$BUILD_CONFIGURATION" -e MONGODB__URI="${MONGODB_URI}" --results-directory "./artifacts/test-results" --logger "junit;LogFileName=TEST_{assembly}.xml;FailureBodyFormat=Verbose" --logger "console;verbosity=detailed" 25 | 26 | echo "Revert changes for test project: $TESTS_PROJECT" 27 | dotnet remove "$TESTS_PROJECT" package "MongoDB.EntityFrameworkCore" 28 | dotnet add "$TESTS_PROJECT" reference "$EFCORE_PROVIDER_PROJECT" 29 | 30 | dotnet nuget remove source local --configfile "./nuget.config" 31 | -------------------------------------------------------------------------------- /evergreen/run-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o errexit # Exit the script with error if any of the commands fail 3 | 4 | MONGODB_URI=${MONGODB_URI:=mongodb://localhost:27017/} 5 | BUILD_CONFIGURATION=${BUILD_CONFIGURATION:=Debug} 6 | 7 | EFCORE_PROVIDER_PROJECT_PATH="./src/MongoDB.EntityFrameworkCore/MongoDB.EntityFrameworkCore.csproj" 8 | if [ -n "$DRIVER_VERSION" ] 9 | then 10 | ## Update Driver's package reference if specified 11 | if [ "$DRIVER_VERSION" = "latest" ] 12 | then 13 | echo "Installing the latest version of MongoDB.Driver..." 14 | dotnet remove "$EFCORE_PROVIDER_PROJECT_PATH" package MongoDB.Driver 15 | dotnet add "$EFCORE_PROVIDER_PROJECT_PATH" package MongoDB.Driver 16 | else 17 | echo "Installing the $DRIVER_VERSION version of MongoDB.Driver..." 18 | dotnet remove "$EFCORE_PROVIDER_PROJECT_PATH" package MongoDB.Driver 19 | dotnet add "$EFCORE_PROVIDER_PROJECT_PATH" package MongoDB.Driver -v "$DRIVER_VERSION" 20 | fi 21 | fi 22 | 23 | echo "Running EF Core tests for '${BUILD_CONFIGURATION}' configuration" 24 | dotnet clean "./MongoDB.EFCoreProvider.sln" 25 | dotnet test "./MongoDB.EFCoreProvider.sln" -e MONGODB_URI="${MONGODB_URI}" -c "${BUILD_CONFIGURATION}" --results-directory ./artifacts/test-results/${BUILD_CONFIGURATION// /} --logger "junit;LogFileName=TEST_{assembly}.xml;FailureBodyFormat=Verbose" --logger "console;verbosity=detailed" 26 | -------------------------------------------------------------------------------- /evergreen/sign-packages.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o errexit # Exit the script with error if any of the commands fail 3 | 4 | # Environment variables used as input: 5 | # ARTIFACTORY_PASSWORD 6 | # ARTIFACTORY_USERNAME 7 | # GRS_USERNAME 8 | # GRS_PASSWORD 9 | # PACKAGE_VERSION 10 | 11 | echo "${ARTIFACTORY_PASSWORD}" | docker login --password-stdin --username "${ARTIFACTORY_USERNAME}" artifactory.corp.mongodb.com 12 | 13 | echo "GRS_CONFIG_USER1_USERNAME=${GRS_USERNAME}" >> "signing-envfile" 14 | echo "GRS_CONFIG_USER1_PASSWORD=${GRS_PASSWORD}" >> "signing-envfile" 15 | 16 | docker run --platform="linux/amd64" --env-file=signing-envfile --rm -v $(pwd):/workdir -w /workdir \ 17 | artifactory.corp.mongodb.com/release-tools-container-registry-local/garasign-jsign \ 18 | /bin/bash -c "jsign --tsaurl "http://timestamp.digicert.com" -a ${AUTHENTICODE_KEY_NAME} "./artifacts/nuget/*.$PACKAGE_VERSION.nupkg"" 19 | -------------------------------------------------------------------------------- /evergreen/template_ssdlc_compliance_report.md: -------------------------------------------------------------------------------- 1 | # ${PRODUCT_NAME} SSDLC compliance report 2 | 3 | This report is available 4 | here. 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
Product name${PRODUCT_NAME}
Product version${PACKAGE_VERSION}
Report date, UTC${REPORT_DATE_UTC}
20 | 21 | ## Release creator 22 | 23 | This information is available in multiple ways: 24 | 25 | 26 | 27 | 28 | 31 | 32 | 33 | 34 | 37 | 38 |
Evergreen 29 | See the "Submitted by" field in Evergreen release task. 30 |
Papertrail 35 | Refer to data in Papertrail. There is currently no official way to serve that data. 36 |
39 | 40 | ## Process document 41 | 42 | Blocked on . 43 | 44 | The MongoDB SSDLC policy is available here. 45 | 46 | ## Third-party dependency information 47 | 48 | Our third party report is available here. 49 | 50 | ## Static analysis findings 51 | 52 | Coverity static analysis report is available here. 53 | 54 | ## Signature information 55 | 56 | Packages are signed with certificate with fingerprint: ${NUGET_SIGN_CERTIFICATE_FINGERPRINT}. 57 | Signature can be validated by running ```dotnet nuget verify``` command. 58 | 59 | For example signature of ```MongoDB.EntityFrameworkCore.${PACKAGE_VERSION}.nupkg``` package can be verified by running: 60 | ``` 61 | dotnet nuget verify MongoDB.EntityFrameworkCore.${PACKAGE_VERSION}.nupkg --certificate-fingerprint ${NUGET_SIGN_CERTIFICATE_FINGERPRINT} 62 | ``` 63 | -------------------------------------------------------------------------------- /evergreen/upload-apidocs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -o errexit # Exit the script with error if any of the commands fail 3 | 4 | DOCS_REPO="https://${GITHUB_USER}:${GITHUB_APIKEY}@github.com/mongodb/mongo-efcore-provider.git" 5 | 6 | echo "Prepare github docs" 7 | git clone "$DOCS_REPO" ./gh-pages/ --branch gh-pages --single-branch 8 | 9 | mkdir ./gh-pages/"$PACKAGE_VERSION"/ 10 | cp -r ./artifacts/apidocs/"$PACKAGE_VERSION"/. ./gh-pages/"$PACKAGE_VERSION"/ 11 | 12 | cd ./gh-pages 13 | 14 | git add --all 15 | git commit -m "Add $PACKAGE_VERSION Api docs" --author="Build Agent" 16 | git push --repo="$DOCS_REPO" 17 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "8.0.0", 4 | "rollForward": "latestMajor", 5 | "allowPrerelease": false 6 | } 7 | } -------------------------------------------------------------------------------- /nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packageIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mongodb/mongo-efcore-provider/1e2e1c63ecab1af01df910ba385db1cfd244b3a0/packageIcon.png -------------------------------------------------------------------------------- /sbom.json: -------------------------------------------------------------------------------- 1 | { 2 | "serialNumber": "urn:uuid:abde4013-504f-45bb-9bdc-2ffa7b4bf591", 3 | "version": 1, 4 | "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", 5 | "bomFormat": "CycloneDX", 6 | "specVersion": "1.5" 7 | } 8 | -------------------------------------------------------------------------------- /src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | MongoDB Inc. 4 | Copyright © 2023-present MongoDB Inc. 5 | MongoDB Inc. 6 | packageIcon.png 7 | README.md 8 | https://github.com/mongodb/mongo-efcore-provider/releases/tag/v$(Version) 9 | true 10 | https://www.mongodb.com/docs/entity-framework/ 11 | mongodb;mongo;nosql;efcore 12 | LICENSE.md 13 | en-US 14 | true 15 | snupkg 16 | true 17 | true 18 | 19 | 20 | 21 | 22 | all 23 | runtime; build; native; contentfiles; analyzers 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Design/MongoDesignTimeServices.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Design; 17 | using Microsoft.EntityFrameworkCore.Design.Internal; 18 | using Microsoft.Extensions.DependencyInjection; 19 | 20 | [assembly: DesignTimeProviderServices("MongoDB.EntityFrameworkCore.Design.MongoDesignTimeServices")] 21 | 22 | namespace MongoDB.EntityFrameworkCore.Design; 23 | 24 | /// 25 | public class MongoDesignTimeServices : IDesignTimeServices 26 | { 27 | /// 28 | public virtual void ConfigureDesignTimeServices(IServiceCollection serviceCollection) 29 | { 30 | serviceCollection.AddEntityFrameworkMongoDB(); 31 | new EntityFrameworkDesignServicesBuilder(serviceCollection) 32 | .TryAdd() 33 | .TryAddCoreServices(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Diagnostics/MongoLoggingDefinitions.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Diagnostics; 17 | 18 | namespace MongoDB.EntityFrameworkCore.Diagnostics; 19 | 20 | /// 21 | /// MongoDB-specific logging definitions. 22 | /// 23 | internal class MongoLoggingDefinitions : LoggingDefinitions 24 | { 25 | public EventDefinitionBase? LogExecutedMqlQuery; 26 | 27 | public EventDefinitionBase? LogExecutingBulkWrite; 28 | public EventDefinitionBase? LogExecutedBulkWrite; 29 | 30 | public EventDefinitionBase? LogBeginningTransaction; 31 | public EventDefinitionBase? LogBeganTransaction; 32 | 33 | public EventDefinitionBase? LogCommittingTransaction; 34 | public EventDefinitionBase? LogCommittedTransaction; 35 | 36 | public EventDefinitionBase? LogRollingBackTransaction; 37 | public EventDefinitionBase? LogRolledBackTransaction; 38 | 39 | public EventDefinitionBase? LogTransactionError; 40 | } 41 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Diagnostics/MongoQueryEventData.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using System.Diagnostics; 18 | using Microsoft.EntityFrameworkCore.Diagnostics; 19 | using MongoDB.Driver; 20 | 21 | namespace MongoDB.EntityFrameworkCore.Diagnostics; 22 | 23 | /// 24 | /// A event payload class for MongoDB query events. 25 | /// 26 | /// 27 | /// See Logging, events, and diagnostics for more information and examples. 28 | /// 29 | public class MongoQueryEventData : EventData 30 | { 31 | /// 32 | /// Constructs the event payload. 33 | /// 34 | /// The event definition. 35 | /// A delegate that generates a log message for this event. 36 | /// The being queried. 37 | /// The MQL representing the query. 38 | /// Indicates whether the application allows logging of sensitive data. 39 | public MongoQueryEventData( 40 | EventDefinitionBase eventDefinition, 41 | Func messageGenerator, 42 | CollectionNamespace collectionNamespace, 43 | string queryMql, 44 | bool logSensitiveData) 45 | : base(eventDefinition, messageGenerator) 46 | { 47 | CollectionNamespace = collectionNamespace; 48 | QueryMql = queryMql; 49 | LogSensitiveData = logSensitiveData; 50 | } 51 | 52 | /// 53 | /// The being queried. 54 | /// 55 | public virtual CollectionNamespace CollectionNamespace { get; } 56 | 57 | /// 58 | /// The MQL representing the query. 59 | /// 60 | public virtual string QueryMql { get; } 61 | 62 | /// 63 | /// Indicates whether the application allows logging of sensitive data. 64 | /// 65 | public virtual bool LogSensitiveData { get; } 66 | } 67 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Diagnostics/MongoTransactionEndEventData.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using System.Diagnostics; 18 | using Microsoft.EntityFrameworkCore.Diagnostics; 19 | using MongoDB.EntityFrameworkCore.Storage; 20 | 21 | namespace MongoDB.EntityFrameworkCore.Diagnostics; 22 | 23 | /// 24 | /// A event payload class for MongoDB transaction events. 25 | /// 26 | /// 27 | /// See Logging, events, and diagnostics for more information and examples. 28 | /// 29 | public class MongoTransactionEndEventData : MongoTransactionEventData 30 | { 31 | /// 32 | /// Constructs the event payload. 33 | /// 34 | /// The event definition. 35 | /// A delegate that generates a log message for this event. 36 | /// The . 37 | /// Indicates whether or not the transaction is being used asynchronously. 38 | /// The start time of this event. 39 | /// The duration this event. 40 | public MongoTransactionEndEventData( 41 | EventDefinitionBase eventDefinition, 42 | Func messageGenerator, 43 | MongoTransaction transaction, 44 | bool async, 45 | DateTimeOffset startTime, 46 | TimeSpan duration) 47 | : base(eventDefinition, messageGenerator, transaction, async, startTime) 48 | { 49 | Duration = duration; 50 | } 51 | 52 | /// 53 | /// The duration of this event. 54 | /// 55 | public TimeSpan Duration { get; set; } 56 | } 57 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Diagnostics/MongoTransactionEventData.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using System.Diagnostics; 18 | using Microsoft.EntityFrameworkCore.Diagnostics; 19 | using MongoDB.EntityFrameworkCore.Storage; 20 | 21 | namespace MongoDB.EntityFrameworkCore.Diagnostics; 22 | 23 | /// 24 | /// The event payload base class for transaction events. 25 | /// 26 | /// 27 | /// See Logging, events, and diagnostics for more information and examples. 28 | /// 29 | public class MongoTransactionEventData : DbContextEventData 30 | { 31 | /// 32 | /// Constructs the event payload. 33 | /// 34 | /// The event definition. 35 | /// A delegate that generates a log message for this event. 36 | /// The . 37 | /// Indicates whether or not the transaction is being used asynchronously. 38 | /// The start time of this event. 39 | public MongoTransactionEventData( 40 | EventDefinitionBase eventDefinition, 41 | Func messageGenerator, 42 | MongoTransaction transaction, 43 | bool async, 44 | DateTimeOffset startTime) 45 | : base(eventDefinition, messageGenerator, transaction.Context) 46 | { 47 | Transaction = transaction; 48 | IsAsync = async; 49 | StartTime = startTime; 50 | } 51 | 52 | /// 53 | /// The . 54 | /// 55 | public MongoTransaction Transaction { get; } 56 | 57 | /// 58 | /// Indicates whether or not the transaction is being used asynchronously. 59 | /// 60 | public bool IsAsync { get; } 61 | 62 | /// 63 | /// The start time of this event. 64 | /// 65 | public DateTimeOffset StartTime { get; } 66 | } 67 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Diagnostics/NonCapturingLazyInitializer.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | // Originally from EFCore NonCapturingLazyInitializer.cs 5 | 6 | using System; 7 | using System.Threading; 8 | 9 | namespace MongoDB.EntityFrameworkCore.Diagnostics; 10 | 11 | internal static class NonCapturingLazyInitializer 12 | { 13 | public static TValue EnsureInitialized( 14 | ref TValue? target, 15 | TParam param, 16 | Func valueFactory) 17 | where TValue : class 18 | { 19 | var tmp = Volatile.Read(ref target); 20 | if (tmp != null) 21 | { 22 | return tmp; 23 | } 24 | 25 | Interlocked.CompareExchange(ref target, valueFactory(param), null); 26 | 27 | return target; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/EnumerableMethods.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | // Originally EF Core EnumerableMethods.cs 5 | 6 | using System; 7 | using System.Collections; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using System.Reflection; 11 | 12 | namespace MongoDB.EntityFrameworkCore; 13 | 14 | internal static class EnumerableMethods 15 | { 16 | static EnumerableMethods() 17 | { 18 | var queryableMethodGroups = typeof(Enumerable) 19 | .GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly) 20 | .GroupBy(mi => mi.Name) 21 | .ToDictionary(e => e.Key, l => l.ToList()); 22 | 23 | GetMethod( 24 | nameof(Enumerable.All), 1, 25 | types => 26 | [ 27 | typeof(IEnumerable<>).MakeGenericType(types[0]), typeof(Func<,>).MakeGenericType(types[0], typeof(bool)) 28 | ]); 29 | 30 | Cast = GetMethod(nameof(Enumerable.Cast), 1, _ => 31 | [ 32 | typeof(IEnumerable) 33 | ]); 34 | 35 | Select = GetMethod( 36 | nameof(Enumerable.Select), 2, 37 | types => [typeof(IEnumerable<>).MakeGenericType(types[0]), typeof(Func<,>).MakeGenericType(types[0], types[1])]); 38 | 39 | SelectWithOrdinal = GetMethod( 40 | nameof(Enumerable.Select), 2, 41 | types => 42 | [ 43 | typeof(IEnumerable<>).MakeGenericType(types[0]), typeof(Func<,,>).MakeGenericType(types[0], typeof(int), types[1]) 44 | ]); 45 | 46 | MethodInfo GetMethod(string name, int genericParameterCount, Func parameterGenerator) 47 | { 48 | return queryableMethodGroups[name].Single( 49 | mi => (genericParameterCount == 0 && !mi.IsGenericMethod 50 | || mi.IsGenericMethod && mi.GetGenericArguments().Length == genericParameterCount) 51 | && mi.GetParameters().Select(e => e.ParameterType).SequenceEqual( 52 | parameterGenerator(mi.IsGenericMethod ? mi.GetGenericArguments() : []))); 53 | } 54 | } 55 | 56 | public static MethodInfo Cast { get; } 57 | public static MethodInfo Select { get; } 58 | public static MethodInfo SelectWithOrdinal { get; } 59 | } 60 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/ExceptionHelpers.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using System.Runtime.CompilerServices; 18 | 19 | namespace MongoDB.EntityFrameworkCore; 20 | 21 | internal static class ExceptionHelpers 22 | { 23 | public static void ThrowArgumentExceptionIfNullOrEmpty( 24 | this string? argument, 25 | [CallerArgumentExpression("argument")] string? paramName = null) 26 | { 27 | if (string.IsNullOrEmpty(argument)) 28 | { 29 | throw argument is null 30 | ? new ArgumentNullException(paramName) 31 | : new ArgumentException("The value cannot be an empty string.", paramName); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/ExpressionExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using System.Linq.Expressions; 18 | 19 | namespace MongoDB.EntityFrameworkCore; 20 | 21 | internal static class ExpressionExtensionMethods 22 | { 23 | internal static T GetConstantValue(this Expression expression) 24 | => expression is ConstantExpression constantExpression 25 | ? (T)constantExpression.Value! 26 | : throw new InvalidOperationException(); 27 | 28 | internal static LambdaExpression UnwrapLambdaFromQuote(this Expression expression) 29 | => (LambdaExpression)(expression is UnaryExpression unary && expression.NodeType == ExpressionType.Quote 30 | ? unary.Operand 31 | : expression); 32 | } 33 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Extensions/MongoNavigationExtensions.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Metadata; 17 | 18 | namespace MongoDB.EntityFrameworkCore.Extensions; 19 | 20 | /// 21 | /// MongoDB-specific extension methods for . 22 | /// 23 | public static class MongoNavigationExtensions 24 | { 25 | /// 26 | /// Determine whether a navigation is embedded or not. 27 | /// 28 | /// The to consider. 29 | /// 30 | /// if the navigation is embedded, 31 | /// if it is not. 32 | /// 33 | public static bool IsEmbedded(this IReadOnlyNavigation navigation) 34 | => !navigation.IsOnDependent 35 | && !navigation.ForeignKey.DeclaringEntityType.IsDocumentRoot(); 36 | } 37 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Infrastructure/IMongoDbContextOptionsBuilderInfrastructure.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | 18 | namespace MongoDB.EntityFrameworkCore.Infrastructure; 19 | 20 | /// 21 | /// Explicitly implemented by to hide methods that are used by database provider 22 | /// extension methods but not intended to be called by application developers. 23 | /// 24 | public interface IMongoDbContextOptionsBuilderInfrastructure 25 | { 26 | /// 27 | /// Gets the core options builder. 28 | /// 29 | DbContextOptionsBuilder OptionsBuilder { get; } 30 | } 31 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Infrastructure/MongoDbContextOptionsBuilder.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | 18 | namespace MongoDB.EntityFrameworkCore.Infrastructure; 19 | 20 | /// 21 | /// Allows MongoDB-specific configuration to be performed on . 22 | /// 23 | public class MongoDbContextOptionsBuilder : IMongoDbContextOptionsBuilderInfrastructure 24 | { 25 | /// 26 | /// Creates a with the required options builder. 27 | /// 28 | /// The to start from. 29 | public MongoDbContextOptionsBuilder(DbContextOptionsBuilder optionsBuilder) 30 | { 31 | OptionsBuilder = optionsBuilder; 32 | } 33 | 34 | /// 35 | /// Clones the configuration in this builder. 36 | /// 37 | /// The cloned configuration. 38 | protected virtual DbContextOptionsBuilder OptionsBuilder { get; } 39 | 40 | DbContextOptionsBuilder IMongoDbContextOptionsBuilderInfrastructure.OptionsBuilder => OptionsBuilder; 41 | } 42 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Infrastructure/MongoModelRuntimeInitializer.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Diagnostics; 18 | using Microsoft.EntityFrameworkCore.Infrastructure; 19 | using Microsoft.EntityFrameworkCore.Metadata; 20 | 21 | namespace MongoDB.EntityFrameworkCore.Infrastructure; 22 | 23 | /// 24 | /// Initializes a with the runtime dependencies. 25 | /// 26 | /// 27 | public class MongoModelRuntimeInitializer(ModelRuntimeInitializerDependencies dependencies) 28 | : ModelRuntimeInitializer(dependencies) 29 | { 30 | /// 31 | /// Validates and initializes the given model with runtime dependencies. 32 | /// 33 | /// 34 | /// Specifically, this method initializes the MongoDB C# Driver with the necessary 35 | /// configuration to support the model and MongoDB EF Core provider. 36 | /// 37 | /// The model to initialize. 38 | /// Whether the model should contain design-time configuration. 39 | /// The validation logger. 40 | /// The initialized model. 41 | public override IModel Initialize(IModel model, bool designTime = true, 42 | IDiagnosticsLogger? validationLogger = null) 43 | { 44 | model = base.Initialize(model, designTime, validationLogger); 45 | return model; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Attributes/CollectionAttribute.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | 18 | // ReSharper disable once CheckNamespace 19 | namespace MongoDB.EntityFrameworkCore; 20 | 21 | /// 22 | /// Specifies the collection that an entity is mapped to. 23 | /// 24 | [AttributeUsage(AttributeTargets.Class)] 25 | public class CollectionAttribute : Attribute 26 | { 27 | /// 28 | /// Creates a with the required collection name. 29 | /// 30 | /// Name of the collection to map the attributed type to. 31 | public CollectionAttribute(string name) 32 | { 33 | if (string.IsNullOrWhiteSpace(name)) 34 | { 35 | throw new ArgumentException($"The argument '{nameof(name)}' cannot be null, empty or contain only whitespace.", 36 | nameof(name)); 37 | } 38 | 39 | Name = name; 40 | } 41 | 42 | /// 43 | /// The name of the collection the type is mapped to. 44 | /// 45 | public string Name { get; } 46 | } 47 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/BsonAttributes/BsonDateTimeOptionsAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using System.Reflection; 18 | using Microsoft.EntityFrameworkCore; 19 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 20 | using Microsoft.EntityFrameworkCore.Metadata.Conventions; 21 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 22 | using MongoDB.Bson.Serialization.Attributes; 23 | 24 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions.BsonAttributes; 25 | 26 | /// 27 | /// A convention that configures the element name for entity properties based on an applied for 28 | /// familiarity with the Mongo C# Driver. 29 | /// 30 | public sealed class BsonDateTimeOptionsAttributeConvention : PropertyAttributeConventionBase 31 | { 32 | /// 33 | /// Creates a . 34 | /// 35 | /// Parameter object containing dependencies for this convention. 36 | public BsonDateTimeOptionsAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) 37 | : base(dependencies) 38 | { 39 | } 40 | 41 | /// 42 | protected override void ProcessPropertyAdded( 43 | IConventionPropertyBuilder propertyBuilder, 44 | BsonDateTimeOptionsAttribute attribute, 45 | MemberInfo clrMember, 46 | IConventionContext context) 47 | { 48 | if (attribute.DateOnly) 49 | { 50 | throw new NotSupportedException( 51 | $"{nameof(BsonDateTimeOptionsAttribute)} with ${nameof(DateOnly)} of true not currently supported."); 52 | } 53 | 54 | propertyBuilder.HasDateTimeKind(attribute.Kind); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/BsonAttributes/BsonDefaultValueAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 17 | using MongoDB.Bson.Serialization.Attributes; 18 | 19 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions.BsonAttributes; 20 | 21 | /// 22 | /// Recognize when applied to properties of an entity 23 | /// to ensure the model will throw as the attribute is not supported in the EF provider. 24 | /// 25 | /// The conventions depend upon. 26 | public sealed class BsonDefaultValueAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) 27 | : NotSupportedPropertyAttributeConvention(dependencies); 28 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/BsonAttributes/BsonDictionaryOptionsAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 17 | using MongoDB.Bson.Serialization.Attributes; 18 | 19 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions.BsonAttributes; 20 | 21 | /// 22 | /// Recognize when applied to properties of an entity 23 | /// to ensure the model will throw as the attribute is not supported in the EF provider. 24 | /// 25 | /// The conventions depend upon. 26 | public sealed class BsonDictionaryOptionsAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) 27 | : NotSupportedPropertyAttributeConvention(dependencies); 28 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/BsonAttributes/BsonExtraElementsAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 17 | using MongoDB.Bson.Serialization.Attributes; 18 | 19 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions.BsonAttributes; 20 | 21 | /// 22 | /// Recognize when applied to properties of an entity 23 | /// to ensure the model will throw as the attribute is not supported in the EF provider. 24 | /// 25 | /// The conventions depend upon. 26 | public sealed class BsonExtraElementsAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) 27 | : NotSupportedPropertyAttributeConvention(dependencies); 28 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/BsonAttributes/BsonGuidRepresentationAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 17 | using MongoDB.Bson.Serialization.Attributes; 18 | 19 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions.BsonAttributes; 20 | 21 | /// 22 | /// Recognize when applied to properties of an entity 23 | /// to ensure the model will throw as the attribute is not supported in the EF provider. 24 | /// 25 | /// The conventions depend upon. 26 | public sealed class BsonGuidRepresentationAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) 27 | : NotSupportedPropertyAttributeConvention(dependencies); 28 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/BsonAttributes/BsonIgnoreIfDefaultAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 17 | using MongoDB.Bson.Serialization.Attributes; 18 | 19 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions.BsonAttributes; 20 | 21 | /// 22 | /// Recognize when applied to properties of an entity 23 | /// to ensure the model will throw as the attribute is not supported in the EF provider. 24 | /// 25 | /// The conventions depend upon. 26 | public sealed class BsonIgnoreIfDefaultAttributePropertyAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) 27 | : NotSupportedPropertyAttributeConvention(dependencies); 28 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/BsonAttributes/BsonIgnoreIfNullAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 17 | using MongoDB.Bson.Serialization.Attributes; 18 | 19 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions.BsonAttributes; 20 | 21 | /// 22 | /// Recognize when applied to properties of an entity 23 | /// to ensure the model will throw as the attribute is not supported in the EF provider. 24 | /// 25 | /// The conventions depend upon. 26 | public sealed class BsonIgnoreIfNullAttributePropertyAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) 27 | : NotSupportedPropertyAttributeConvention(dependencies); 28 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/BsonAttributes/BsonRepresentationAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using System.Reflection; 18 | using Microsoft.EntityFrameworkCore; 19 | using Microsoft.EntityFrameworkCore.Infrastructure; 20 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 21 | using Microsoft.EntityFrameworkCore.Metadata.Conventions; 22 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 23 | using MongoDB.Bson.Serialization.Attributes; 24 | 25 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions.BsonAttributes; 26 | 27 | /// 28 | /// A convention that configures the element name for entity properties based on an applied for 29 | /// familiarity with the Mongo C# Driver. 30 | /// 31 | public sealed class BsonRepresentationAttributeConvention : PropertyAttributeConventionBase 32 | { 33 | /// 34 | /// Creates a . 35 | /// 36 | /// Parameter object containing dependencies for this convention. 37 | public BsonRepresentationAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) 38 | : base(dependencies) 39 | { 40 | } 41 | 42 | /// 43 | protected override void ProcessPropertyAdded( 44 | IConventionPropertyBuilder propertyBuilder, 45 | BsonRepresentationAttribute attribute, 46 | MemberInfo clrMember, 47 | IConventionContext context) 48 | { 49 | if (!Enum.IsDefined(attribute.Representation)) 50 | { 51 | throw new NotSupportedException( 52 | $"Property '{clrMember.DeclaringType!.ShortDisplayName()}.{clrMember.Name}' has {nameof(BsonRepresentationAttribute)} of {attribute.Representation} which a not supported type."); 53 | } 54 | 55 | propertyBuilder.HasBsonRepresentation(attribute.Representation, attribute.AllowOverflow, attribute.AllowTruncation); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/BsonAttributes/BsonRequiredAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Reflection; 17 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 18 | using Microsoft.EntityFrameworkCore.Metadata.Conventions; 19 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 20 | using MongoDB.Bson.Serialization.Attributes; 21 | 22 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions.BsonAttributes; 23 | 24 | /// 25 | /// A convention that configures properties as required if they have the applied. 26 | /// 27 | public sealed class BsonRequiredPropertyAttributeConvention : PropertyAttributeConventionBase, 28 | IComplexPropertyAddedConvention, 29 | IComplexPropertyFieldChangedConvention 30 | { 31 | /// 32 | /// Creates a new instance of . 33 | /// 34 | /// Parameter object containing dependencies for this convention. 35 | public BsonRequiredPropertyAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) 36 | : base(dependencies) 37 | { 38 | } 39 | 40 | /// 41 | protected override void ProcessPropertyAdded( 42 | IConventionPropertyBuilder propertyBuilder, 43 | BsonRequiredAttribute attribute, 44 | MemberInfo clrMember, 45 | IConventionContext context) 46 | => propertyBuilder.IsRequired(true, fromDataAnnotation: true); 47 | 48 | /// 49 | protected override void ProcessPropertyAdded( 50 | IConventionComplexPropertyBuilder propertyBuilder, 51 | BsonRequiredAttribute attribute, 52 | MemberInfo clrMember, 53 | IConventionContext context) 54 | => propertyBuilder.IsRequired(true, fromDataAnnotation: true); 55 | } 56 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/BsonAttributes/BsonSerializationOptionsAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Reflection; 17 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 18 | using Microsoft.EntityFrameworkCore.Metadata.Conventions; 19 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 20 | using MongoDB.Bson.Serialization.Attributes; 21 | 22 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions.BsonAttributes; 23 | 24 | /// 25 | /// Recognized applied to properties of an entity 26 | /// to ensure the model throw later as it is not supported in the EF provider. 27 | /// 28 | /// The conventions depend upon. 29 | public sealed class BsonSerializationOptionsAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) 30 | : NotSupportedPropertyAttributeConvention(dependencies) 31 | { 32 | /// 33 | protected override void ProcessPropertyAdded( 34 | IConventionPropertyBuilder propertyBuilder, 35 | BsonSerializationOptionsAttribute attribute, 36 | MemberInfo clrMember, 37 | IConventionContext context) 38 | { 39 | // DateTimeOptions & BsonRepresentation are supported and are subclasses so do not treat them as unsupported 40 | if (attribute is BsonDateTimeOptionsAttribute or BsonRepresentationAttribute) return; 41 | 42 | base.ProcessPropertyAdded(propertyBuilder, attribute, clrMember, context); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/BsonAttributes/BsonSerializerPropertyConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 17 | using MongoDB.Bson.Serialization.Attributes; 18 | 19 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions.BsonAttributes; 20 | 21 | /// 22 | /// Recognize when applied to properties of an entity 23 | /// to ensure the model will throw as the attribute is not supported in the EF provider. 24 | /// 25 | /// The conventions depend upon. 26 | public sealed class BsonSerializerPropertyConvention(ProviderConventionSetBuilderDependencies dependencies) 27 | : NotSupportedPropertyAttributeConvention(dependencies); 28 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/BsonAttributes/BsonTimeSpanOptionsAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 17 | using MongoDB.Bson.Serialization.Attributes; 18 | 19 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions.BsonAttributes; 20 | 21 | /// 22 | /// Recognize when applied to properties of an entity 23 | /// to ensure the model will throw as the attribute is not supported in the EF provider. 24 | /// 25 | /// The conventions depend upon. 26 | public sealed class BsonTimeSpanOptionsPropertyAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) 27 | : NotSupportedPropertyAttributeConvention(dependencies); 28 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/CollectionAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 17 | using Microsoft.EntityFrameworkCore.Metadata.Conventions; 18 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 19 | using MongoDB.EntityFrameworkCore.Extensions; 20 | 21 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions; 22 | 23 | /// 24 | /// A convention that configures the collection name for entity types based on the applied . 25 | /// 26 | public class CollectionAttributeConvention : TypeAttributeConventionBase 27 | { 28 | /// 29 | /// Creates a . 30 | /// 31 | /// Parameter object containing dependencies for this convention. 32 | public CollectionAttributeConvention( 33 | ProviderConventionSetBuilderDependencies dependencies) 34 | : base(dependencies) 35 | { 36 | } 37 | 38 | /// 39 | /// Called after an entity type is added to the model if it has an attribute. 40 | /// 41 | /// The builder for the entity type. 42 | /// The attribute. 43 | /// Additional information associated with convention execution. 44 | protected override void ProcessEntityTypeAdded( 45 | IConventionEntityTypeBuilder entityTypeBuilder, 46 | CollectionAttribute attribute, 47 | IConventionContext context) 48 | { 49 | if (!string.IsNullOrWhiteSpace(attribute.Name)) 50 | { 51 | entityTypeBuilder.ToCollection(attribute.Name, fromDataAnnotation: true); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/DateTimeKindConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using Microsoft.EntityFrameworkCore; 18 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 19 | using Microsoft.EntityFrameworkCore.Metadata.Conventions; 20 | 21 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions; 22 | 23 | /// 24 | /// A convention that set for properties. 25 | /// 26 | public class DateTimeKindConvention : IPropertyAddedConvention 27 | { 28 | /// 29 | /// Creates a . 30 | /// 31 | /// to use 32 | public DateTimeKindConvention(DateTimeKind dateTimeKind) 33 | { 34 | DateTimeKind = dateTimeKind; 35 | } 36 | 37 | /// 38 | /// to use. 39 | /// 40 | protected DateTimeKind DateTimeKind { get; } 41 | 42 | /// 43 | /// For every property of type that is added to the model set the configured . 44 | /// 45 | /// 46 | /// 47 | public void ProcessPropertyAdded( 48 | IConventionPropertyBuilder propertyBuilder, 49 | IConventionContext context) 50 | { 51 | var clrType = propertyBuilder.Metadata.ClrType.UnwrapNullableType(); 52 | 53 | if (clrType != typeof(DateTime)) 54 | { 55 | return; 56 | } 57 | 58 | propertyBuilder.HasDateTimeKind(DateTimeKind); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/MongoRelationshipDiscoveryConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using System.Collections.Generic; 18 | using Microsoft.EntityFrameworkCore.Metadata; 19 | using Microsoft.EntityFrameworkCore.Metadata.Conventions; 20 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 21 | 22 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions; 23 | 24 | /// 25 | /// A convention that ensures embedded objects are correctly configured as owned entities. 26 | /// 27 | public class MongoRelationshipDiscoveryConvention : RelationshipDiscoveryConvention 28 | { 29 | /// 30 | /// Creates a . 31 | /// 32 | /// The required by this convention. 33 | public MongoRelationshipDiscoveryConvention(ProviderConventionSetBuilderDependencies dependencies) 34 | : base(dependencies) 35 | { 36 | } 37 | 38 | /// 39 | protected override bool? ShouldBeOwned(Type targetType, IConventionModel model) 40 | => ShouldBeOwnedType(targetType, model); 41 | 42 | /// 43 | /// Determine if a given entity type should be added as an owned entity if not already in the model. 44 | /// 45 | /// Target entity . 46 | /// The being built. 47 | /// if the type is to be owned, otherwise. 48 | public static bool ShouldBeOwnedType( 49 | Type targetType, 50 | IConventionModel model) 51 | => !targetType.IsGenericType 52 | || targetType == typeof(Dictionary) 53 | || targetType.GetInterface(typeof(IEnumerable<>).Name) == null; 54 | } 55 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/Conventions/NotSupportedPropertyAttributeConvention.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using System.Reflection; 18 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 19 | using Microsoft.EntityFrameworkCore.Metadata.Conventions; 20 | using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; 21 | using MongoDB.EntityFrameworkCore.Infrastructure; 22 | 23 | namespace MongoDB.EntityFrameworkCore.Metadata.Conventions; 24 | 25 | /// 26 | /// Abstract class to register unsupported attributes on properties as 27 | /// allowing to throw when encountered. 28 | /// 29 | /// The conventions depend upon. 30 | /// The type of to register as unsupported. 31 | public abstract class NotSupportedPropertyAttributeConvention(ProviderConventionSetBuilderDependencies dependencies) 32 | : PropertyAttributeConventionBase(dependencies) where T : Attribute 33 | { 34 | /// 35 | protected override void ProcessPropertyAdded( 36 | IConventionPropertyBuilder propertyBuilder, 37 | T attribute, 38 | MemberInfo clrMember, 39 | IConventionContext context) 40 | { 41 | var meta = propertyBuilder.Metadata; 42 | meta.SetAnnotation(MongoAnnotationNames.NotSupportedAttributes, attribute); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Metadata/MongoAnnotationNames.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | namespace MongoDB.EntityFrameworkCore.Metadata; 17 | 18 | /// 19 | /// Names for well-known Mongo model annotations. Applications should not use these names 20 | /// directly, but should instead use the extension methods on metadata objects. 21 | /// 22 | public static class MongoAnnotationNames 23 | { 24 | /// 25 | /// The prefix used for all MongoDB annotations. 26 | /// 27 | public const string Prefix = "Mongo:"; 28 | 29 | /// 30 | /// The key for collection name annotations. 31 | /// 32 | public const string CollectionName = Prefix + nameof(CollectionName); 33 | 34 | /// 35 | /// The key for document element name annotations. 36 | /// 37 | public const string ElementName = Prefix + nameof(ElementName); 38 | 39 | /// 40 | /// The key for annotations. 41 | /// 42 | public const string DateTimeKind = Prefix + nameof(DateTimeKind); 43 | 44 | /// 45 | /// The key for marking annotations as not supported. 46 | /// 47 | public const string NotSupportedAttributes = Prefix + nameof(NotSupportedAttributes); 48 | 49 | /// 50 | /// The key for Bson representation annotations. 51 | /// 52 | public const string BsonRepresentation = Prefix + nameof(BsonRepresentation); 53 | 54 | /// 55 | /// The key for create index options annotations. 56 | /// 57 | public const string CreateIndexOptions = Prefix + nameof(CreateIndexOptions); 58 | } 59 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/MongoDB.EntityFrameworkCore.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net8.0 4 | Official MongoDB supported provider for Entity Framework Core. See https://www.mongodb.com/docs/entity-framework/ for more details. 5 | true 6 | MongoDB.EntityFrameworkCore 7 | Debug;Release;Debug EF9;Release EF9 8 | AnyCPU 9 | 10 | 11 | 12 | EF1001 13 | enable 14 | 15 | 16 | 17 | bin\Debug\MongoDB.EntityFrameworkCore.xml 18 | 19 | 20 | 21 | TRACE;DEBUG;EF9 22 | true 23 | 24 | 25 | 26 | TRACE;RELEASE;EF9 27 | true 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/Expressions/CollectionShaperExpression.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | // Originally from EFCore.Cosmos CollectionShaperExpression. 5 | 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq.Expressions; 9 | using Microsoft.EntityFrameworkCore.Metadata; 10 | using Microsoft.EntityFrameworkCore.Query; 11 | 12 | namespace MongoDB.EntityFrameworkCore.Query.Expressions; 13 | 14 | internal sealed class CollectionShaperExpression : Expression, IPrintableExpression 15 | { 16 | public CollectionShaperExpression( 17 | Expression projection, 18 | Expression innerShaper, 19 | INavigationBase? navigation, 20 | Type elementType) 21 | { 22 | Projection = projection; 23 | InnerShaper = innerShaper; 24 | Navigation = navigation; 25 | ElementType = elementType; 26 | } 27 | 28 | public Expression Projection { get; } 29 | 30 | public Expression InnerShaper { get; } 31 | 32 | public INavigationBase? Navigation { get; } 33 | 34 | public Type ElementType { get; } 35 | 36 | public override ExpressionType NodeType 37 | => ExpressionType.Extension; 38 | 39 | public override Type Type 40 | => Navigation?.ClrType ?? typeof(List<>).MakeGenericType(ElementType); 41 | 42 | protected override Expression VisitChildren(ExpressionVisitor visitor) 43 | { 44 | var projection = visitor.Visit(Projection); 45 | var innerShaper = visitor.Visit(InnerShaper); 46 | 47 | return Update(projection, innerShaper); 48 | } 49 | 50 | public CollectionShaperExpression Update( 51 | Expression projection, 52 | Expression innerShaper) 53 | { 54 | return projection != Projection || innerShaper != InnerShaper 55 | ? new CollectionShaperExpression(projection, innerShaper, Navigation, ElementType) 56 | : this; 57 | } 58 | 59 | void IPrintableExpression.Print(ExpressionPrinter expressionPrinter) 60 | { 61 | expressionPrinter.AppendLine("CollectionShaper:"); 62 | using (expressionPrinter.Indent()) 63 | { 64 | expressionPrinter.Append("("); 65 | expressionPrinter.Visit(Projection); 66 | expressionPrinter.Append(", "); 67 | expressionPrinter.Visit(InnerShaper); 68 | expressionPrinter.AppendLine($", {Navigation?.Name})"); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/Expressions/EntityTypedExpression.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using System.Linq.Expressions; 18 | using Microsoft.EntityFrameworkCore.Metadata; 19 | 20 | namespace MongoDB.EntityFrameworkCore.Query.Expressions; 21 | 22 | /// 23 | /// A base class for any type of that is a 24 | /// that exposes a 25 | /// . 26 | /// 27 | internal abstract class EntityTypedExpression : Expression 28 | { 29 | /// 30 | /// Create a . 31 | /// 32 | /// The for this expression. 33 | protected EntityTypedExpression(IEntityType entityType) 34 | { 35 | EntityType = entityType; 36 | } 37 | 38 | /// 39 | /// The this expression relates to. 40 | /// 41 | public IEntityType EntityType { get; } 42 | 43 | /// 44 | public override ExpressionType NodeType 45 | => ExpressionType.Extension; 46 | 47 | /// 48 | public override Type Type 49 | => EntityType.ClrType; 50 | 51 | /// 52 | public override bool Equals(object? obj) 53 | => obj != null 54 | && (ReferenceEquals(this, obj) 55 | || obj is EntityTypedExpression entityTypedExpression 56 | && Equals(entityTypedExpression)); 57 | 58 | private bool Equals(EntityTypedExpression entityTypedExpression) 59 | => Equals(EntityType, entityTypedExpression.EntityType); 60 | 61 | /// 62 | public override int GetHashCode() 63 | => HashCode.Combine(EntityType); 64 | } 65 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/Expressions/IAccessExpression.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | namespace MongoDB.EntityFrameworkCore.Query.Expressions; 17 | 18 | internal interface IAccessExpression 19 | { 20 | string? Name { get; } 21 | } 22 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/Expressions/MongoCollectionExpression.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Linq.Expressions; 17 | using Microsoft.EntityFrameworkCore.Metadata; 18 | using MongoDB.EntityFrameworkCore.Extensions; 19 | 20 | namespace MongoDB.EntityFrameworkCore.Query.Expressions; 21 | 22 | /// 23 | /// Represents a MongoDB collection in the expression tree. 24 | /// 25 | internal sealed class MongoCollectionExpression : EntityTypedExpression 26 | { 27 | /// 28 | /// Create a for a given . 29 | /// 30 | /// The this collection contains. 31 | public MongoCollectionExpression(IEntityType entityType) 32 | : base(entityType) 33 | { 34 | CollectionName = entityType.GetCollectionName(); 35 | } 36 | 37 | /// 38 | /// The name of this collection in MongoDB. 39 | /// 40 | public string CollectionName { get; } 41 | 42 | /// 43 | protected override Expression VisitChildren(ExpressionVisitor visitor) 44 | => this; 45 | } 46 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/Expressions/ProjectionExpression.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | // Derived from EFCore.Cosmos ProjectionExpression. 5 | 6 | using System; 7 | using System.Linq.Expressions; 8 | 9 | namespace MongoDB.EntityFrameworkCore.Query.Expressions; 10 | 11 | /// 12 | /// Represents an individual member projection within the expression tree. 13 | /// 14 | internal sealed class ProjectionExpression : Expression 15 | { 16 | public ProjectionExpression( 17 | Expression expression, 18 | string? alias, 19 | bool required) 20 | { 21 | Expression = expression; 22 | Alias = alias; 23 | Required = required; 24 | } 25 | 26 | public Expression Expression { get; } 27 | 28 | public string? Alias { get; } 29 | 30 | public bool Required { get; } 31 | 32 | /// 33 | public override Type Type 34 | => Expression.Type; 35 | 36 | /// 37 | public override ExpressionType NodeType 38 | => ExpressionType.Extension; 39 | 40 | /// 41 | protected override Expression VisitChildren(ExpressionVisitor visitor) 42 | => Update(visitor.Visit(Expression)); 43 | 44 | public ProjectionExpression Update(Expression expression) 45 | => expression != Expression 46 | ? new ProjectionExpression(expression, Alias, Required) 47 | : this; 48 | 49 | /// 50 | public override bool Equals(object? obj) 51 | => obj != null 52 | && (ReferenceEquals(this, obj) 53 | || (obj is ProjectionExpression projectionExpression 54 | && Equals(projectionExpression))); 55 | 56 | private bool Equals(ProjectionExpression projectionExpression) 57 | => Alias == projectionExpression.Alias 58 | && Expression.Equals(projectionExpression.Expression) 59 | && Required == projectionExpression.Required; 60 | 61 | /// 62 | public override int GetHashCode() 63 | => HashCode.Combine(Alias, Expression, Required); 64 | } 65 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/Expressions/RootReferenceExpression.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Linq.Expressions; 17 | using Microsoft.EntityFrameworkCore.Metadata; 18 | 19 | namespace MongoDB.EntityFrameworkCore.Query.Expressions; 20 | 21 | /// 22 | /// Represents a reference to the root of the query from within a query expression tree. 23 | /// 24 | internal sealed class RootReferenceExpression : EntityTypedExpression, IAccessExpression 25 | { 26 | public RootReferenceExpression(IEntityType entityType) 27 | : base(entityType) 28 | { 29 | } 30 | 31 | public string? Name 32 | { 33 | get { return null; } 34 | } 35 | 36 | protected override Expression VisitChildren(ExpressionVisitor visitor) 37 | => this; 38 | 39 | public override string ToString() 40 | => "bsonDoc"; 41 | } 42 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/Factories/MongoQueryCompilationContextFactory.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Query; 17 | 18 | namespace MongoDB.EntityFrameworkCore.Query.Factories; 19 | 20 | /// 21 | /// A factory for creating instances. 22 | /// 23 | public class MongoQueryCompilationContextFactory : IQueryCompilationContextFactory 24 | { 25 | /// 26 | /// Create a . 27 | /// 28 | /// The passed to each created instance. 29 | public MongoQueryCompilationContextFactory( 30 | QueryCompilationContextDependencies dependencies) 31 | { 32 | Dependencies = dependencies; 33 | } 34 | 35 | /// 36 | /// The passed to each created by this factory. 37 | /// 38 | protected virtual QueryCompilationContextDependencies Dependencies { get; } 39 | 40 | /// 41 | /// Create a new with the necessary dependencies. 42 | /// 43 | /// if the query to process is asynchronous, if it is synchronous. 44 | /// The newly created . 45 | public virtual QueryCompilationContext Create(bool async) 46 | => new MongoQueryCompilationContext(Dependencies, async); 47 | } 48 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/Factories/MongoQueryContextFactory.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Query; 17 | using MongoDB.EntityFrameworkCore.Storage; 18 | 19 | namespace MongoDB.EntityFrameworkCore.Query.Factories; 20 | 21 | /// 22 | /// A factory for creating instances. 23 | /// 24 | public class MongoQueryContextFactory : IQueryContextFactory 25 | { 26 | /// 27 | /// Create a . 28 | /// 29 | /// The passed to each created instance. 30 | /// The passed to each created instance. 31 | public MongoQueryContextFactory( 32 | QueryContextDependencies dependencies, 33 | IMongoClientWrapper mongoClient) 34 | { 35 | Dependencies = dependencies; 36 | Client = mongoClient; 37 | } 38 | 39 | /// 40 | /// The passed to each created . 41 | /// 42 | protected virtual QueryContextDependencies Dependencies { get; } 43 | 44 | /// 45 | /// Create a new with necessary dependencies. 46 | /// 47 | /// The newly created . 48 | public virtual QueryContext Create() 49 | => new MongoQueryContext(Dependencies, Client); 50 | 51 | /// 52 | /// The passed to each created . 53 | /// 54 | public IMongoClientWrapper Client { get; } 55 | } 56 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/Factories/MongoQueryTranslationPostprocessorFactory.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Query; 17 | 18 | namespace MongoDB.EntityFrameworkCore.Query.Factories; 19 | 20 | /// 21 | /// A factory for creating instances. 22 | /// 23 | public class MongoQueryTranslationPostprocessorFactory : IQueryTranslationPostprocessorFactory 24 | { 25 | /// 26 | /// Create a . 27 | /// 28 | /// The passed to each created instance. 29 | public MongoQueryTranslationPostprocessorFactory( 30 | QueryTranslationPostprocessorDependencies dependencies) 31 | { 32 | Dependencies = dependencies; 33 | } 34 | 35 | /// 36 | /// The passed to each created by this factory. 37 | /// 38 | protected virtual QueryTranslationPostprocessorDependencies Dependencies { get; } 39 | 40 | /// 41 | /// Create a new with the necessary dependencies. 42 | /// 43 | /// The to pass to the new . 44 | /// The newly created . 45 | public virtual QueryTranslationPostprocessor Create(QueryCompilationContext queryCompilationContext) 46 | => new MongoQueryTranslationPostprocessor(Dependencies, queryCompilationContext); 47 | } 48 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/Factories/MongoQueryTranslationPreprocessorFactory.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Query; 17 | 18 | namespace MongoDB.EntityFrameworkCore.Query.Factories; 19 | 20 | /// 21 | /// A factory for creating instances. 22 | /// 23 | public class MongoQueryTranslationPreprocessorFactory : IQueryTranslationPreprocessorFactory 24 | { 25 | /// 26 | /// Create a . 27 | /// 28 | /// The passed to each created instance. 29 | public MongoQueryTranslationPreprocessorFactory( 30 | QueryTranslationPreprocessorDependencies dependencies) 31 | { 32 | Dependencies = dependencies; 33 | } 34 | 35 | /// 36 | /// The passed to each created by this factory. 37 | /// 38 | protected virtual QueryTranslationPreprocessorDependencies Dependencies { get; } 39 | 40 | /// 41 | /// Create a new with the necessary dependencies. 42 | /// 43 | /// The to pass to the new . 44 | /// The newly created . 45 | public virtual QueryTranslationPreprocessor Create(QueryCompilationContext queryCompilationContext) 46 | => new MongoQueryTranslationPreprocessor(Dependencies, queryCompilationContext); 47 | } 48 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/Factories/MongoQueryableMethodTranslatingExpressionVisitorFactory.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Query; 17 | using MongoDB.EntityFrameworkCore.Query.Visitors; 18 | 19 | namespace MongoDB.EntityFrameworkCore.Query.Factories; 20 | 21 | /// 22 | /// A factory for creating instances. 23 | /// 24 | public class MongoQueryableMethodTranslatingExpressionVisitorFactory : IQueryableMethodTranslatingExpressionVisitorFactory 25 | { 26 | /// 27 | /// Create a . 28 | /// 29 | /// The passed to each created instance. 30 | public MongoQueryableMethodTranslatingExpressionVisitorFactory( 31 | QueryableMethodTranslatingExpressionVisitorDependencies dependencies) 32 | { 33 | Dependencies = dependencies; 34 | } 35 | 36 | /// 37 | /// The passed to each created by this factory. 38 | /// 39 | protected virtual QueryableMethodTranslatingExpressionVisitorDependencies Dependencies { get; } 40 | 41 | /// 42 | /// Create a new with necessary dependencies. 43 | /// 44 | /// The to pass to the new visitor. 45 | /// The newly created . 46 | public virtual QueryableMethodTranslatingExpressionVisitor Create(QueryCompilationContext queryCompilationContext) 47 | => new MongoQueryableMethodTranslatingExpressionVisitor(Dependencies, 48 | (MongoQueryCompilationContext)queryCompilationContext); 49 | } 50 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/MongoExecutableQuery.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Linq.Expressions; 17 | using Microsoft.EntityFrameworkCore.Query; 18 | using MongoDB.Driver; 19 | using MongoDB.Driver.Linq; 20 | 21 | namespace MongoDB.EntityFrameworkCore.Query; 22 | 23 | /// 24 | /// Internal use only. 25 | /// A query ready to be executed by the MongoDB LINQ provider. 26 | /// 27 | /// A LINQ query compatible with the MongoDB LINQ provider. 28 | /// Whether many or a single result are expected (or enforced) as a . 29 | /// The MongoDB V3 LINQ that will execute this query. 30 | /// The this query will run against. 31 | public record MongoExecutableQuery(Expression Query, ResultCardinality Cardinality, IMongoQueryProvider Provider, CollectionNamespace CollectionNamespace); 32 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/MongoQueryContext.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Query; 17 | using MongoDB.EntityFrameworkCore.Storage; 18 | 19 | namespace MongoDB.EntityFrameworkCore.Query; 20 | 21 | /// 22 | /// Provides the contextual information for a given query such as which client should execute it and using which dependencies. 23 | /// 24 | public class MongoQueryContext : QueryContext 25 | { 26 | /// 27 | /// Create a . 28 | /// 29 | /// The this context specifies. 30 | /// The to use in executing this query. 31 | public MongoQueryContext( 32 | QueryContextDependencies dependencies, 33 | IMongoClientWrapper mongoClient) 34 | : base(dependencies) 35 | { 36 | MongoClient = mongoClient; 37 | } 38 | 39 | /// 40 | /// The this query should be executed using. 41 | /// 42 | public virtual IMongoClientWrapper MongoClient { get; } 43 | } 44 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/MongoQueryTranslationPostprocessor.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Linq.Expressions; 17 | using Microsoft.EntityFrameworkCore.Query; 18 | using MongoDB.EntityFrameworkCore.Query.Expressions; 19 | 20 | namespace MongoDB.EntityFrameworkCore.Query; 21 | 22 | /// 23 | public class MongoQueryTranslationPostprocessor( 24 | QueryTranslationPostprocessorDependencies dependencies, 25 | QueryCompilationContext queryCompilationContext) 26 | : QueryTranslationPostprocessor(dependencies, queryCompilationContext) 27 | { 28 | /// 29 | public override Expression Process(Expression query) 30 | { 31 | query = base.Process(query); 32 | 33 | if (query is ShapedQueryExpression { QueryExpression: MongoQueryExpression queryExpression }) 34 | { 35 | queryExpression.ApplyProjection(); 36 | } 37 | 38 | return query; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/MongoQueryTranslationPreprocessor.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Linq.Expressions; 17 | using Microsoft.EntityFrameworkCore.Query; 18 | using MongoDB.EntityFrameworkCore.Query.Visitors; 19 | 20 | namespace MongoDB.EntityFrameworkCore.Query; 21 | 22 | /// 23 | public class MongoQueryTranslationPreprocessor( 24 | QueryTranslationPreprocessorDependencies dependencies, 25 | QueryCompilationContext queryCompilationContext) 26 | : QueryTranslationPreprocessor(dependencies, queryCompilationContext) 27 | { 28 | /// 29 | public override Expression Process(Expression query) 30 | { 31 | query = FinalPredicateHoistingVisitor.Hoist(query); 32 | query = new EntityFrameworkDetourExpressionVisitor(queryCompilationContext).Visit(query); 33 | return base.Process(query); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Query/Visitors/Dependencies/MongoShapedQueryCompilingExpressionVisitorDependencies.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using MongoDB.EntityFrameworkCore.Query.Factories; 17 | using MongoDB.EntityFrameworkCore.Serializers; 18 | 19 | namespace MongoDB.EntityFrameworkCore.Query.Visitors.Dependencies; 20 | 21 | /// 22 | /// Dependencies required by which will be supplied by 23 | /// the . 24 | /// 25 | /// The used to cache objects. 26 | public sealed record MongoShapedQueryCompilingExpressionVisitorDependencies(BsonSerializerFactory BsonSerializerFactory); 27 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Serializers/MongoEFDiscriminator.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using System.Linq; 18 | using Microsoft.EntityFrameworkCore; 19 | using Microsoft.EntityFrameworkCore.Infrastructure; 20 | using Microsoft.EntityFrameworkCore.Metadata; 21 | using MongoDB.Bson; 22 | using MongoDB.Bson.IO; 23 | using MongoDB.Bson.Serialization.Conventions; 24 | 25 | namespace MongoDB.EntityFrameworkCore.Serializers; 26 | 27 | /// 28 | /// Provides a bridge between EF Core and the MongoDB C# driver for handling discriminator values. 29 | /// 30 | /// The entity that forms part of the hierarchy. 31 | internal class MongoEFDiscriminator(IReadOnlyEntityType entityType) : 32 | IScalarDiscriminatorConvention 33 | { 34 | private readonly IReadOnlyModel _model = entityType.Model; 35 | 36 | public Type GetActualType(IBsonReader bsonReader, Type nominalType) 37 | => throw new NotImplementedException($"Attempted to resolve type discriminator for '{nominalType.ShortDisplayName()}'."); 38 | 39 | public BsonValue GetDiscriminator(Type nominalType, Type actualType) 40 | { 41 | var actualEntityType = _model.FindEntityType(actualType) 42 | ?? throw new InvalidOperationException($"Entity type '{actualType.ShortDisplayName()}' not found in model."); 43 | return BsonValue.Create(actualEntityType.GetDiscriminatorValue()); 44 | } 45 | 46 | public BsonValue[] GetDiscriminatorsForTypeAndSubTypes(Type type) 47 | { 48 | var entityType = _model.FindEntityType(type) 49 | ?? throw new InvalidOperationException($"Entity type '{type.ShortDisplayName()}' not found in model."); 50 | return entityType.GetDerivedTypes().Prepend(entityType).Select(d => BsonValue.Create(d.GetDiscriminatorValue())).ToArray(); 51 | } 52 | 53 | public string ElementName { get; } = entityType.FindDiscriminatorProperty()?.GetElementName() ?? "_t"; 54 | } 55 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Storage/MongoUpdateBatch.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Collections.Generic; 17 | using System.Linq; 18 | using MongoDB.Driver; 19 | using MongoDB.EntityFrameworkCore.Extensions; 20 | 21 | namespace MongoDB.EntityFrameworkCore.Storage; 22 | 23 | internal class MongoUpdateBatch(string collectionName, List updates) 24 | { 25 | public string CollectionName { get => collectionName; } 26 | public List Updates { get => updates; } 27 | 28 | public long Modified => updates.Count(u => u.Model.ModelType == WriteModelType.UpdateOne); 29 | public long Inserts => updates.Count(u => u.Model.ModelType == WriteModelType.InsertOne); 30 | public long Deletes => updates.Count(u => u.Model.ModelType == WriteModelType.DeleteOne); 31 | 32 | public static IEnumerable CreateBatches(IEnumerable updates) 33 | { 34 | MongoUpdateBatch? batch = null; 35 | foreach (var update in updates) 36 | { 37 | if (batch == null) 38 | { 39 | batch = Create(update); 40 | } 41 | else 42 | { 43 | if (batch.CollectionName == update.Entry.EntityType.GetCollectionName()) 44 | { 45 | batch.Updates.Add(update); 46 | } 47 | else 48 | { 49 | yield return batch; 50 | batch = Create(update); 51 | } 52 | } 53 | } 54 | 55 | if (batch != null) 56 | { 57 | yield return batch; 58 | } 59 | } 60 | 61 | public static MongoUpdateBatch Create(MongoUpdate update) 62 | => new(update.Entry.EntityType.GetCollectionName(), [update]); 63 | } 64 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Storage/RowVersion.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using System.Linq; 18 | using System.Numerics; 19 | using System.Reflection; 20 | using Microsoft.EntityFrameworkCore.Metadata; 21 | using Microsoft.EntityFrameworkCore.Update; 22 | 23 | namespace MongoDB.EntityFrameworkCore.Storage; 24 | 25 | internal static class RowVersion 26 | { 27 | internal static object GetRowVersion(this IUpdateEntry entry, IProperty property) 28 | => GetRowVersionInternalMethodInfo.MakeGenericMethod(property.ClrType).Invoke(null, [entry, property])!; 29 | 30 | internal static bool IsRowVersion(this IReadOnlyProperty property) 31 | => property is {IsConcurrencyToken: true, IsNullable: false, ValueGenerated: ValueGenerated.OnAddOrUpdate} 32 | && SupportedRowVersionTypes.Contains(property.ClrType); 33 | 34 | internal static string DefaultElementName => "_version"; 35 | 36 | private static readonly Type[] SupportedRowVersionTypes = [typeof(int), typeof(uint), typeof(long), typeof(ulong)]; 37 | 38 | private static T GetRowVersionInternal(IUpdateEntry entry, IProperty property) where T : INumber 39 | => entry.GetCurrentValue(property) + T.One; 40 | 41 | private static readonly MethodInfo GetRowVersionInternalMethodInfo = 42 | typeof(RowVersion).GetMethod(nameof(GetRowVersionInternal), BindingFlags.Static | BindingFlags.NonPublic)!; 43 | } 44 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Storage/ValueConversion/Decimal128ToDecimalConverter.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Storage; 17 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 18 | using MongoDB.Bson; 19 | 20 | namespace MongoDB.EntityFrameworkCore.Storage.ValueConversion; 21 | 22 | /// 23 | /// Converts a to and from values. 24 | /// 25 | /// 26 | /// See EF Core value converters for more information and examples. 27 | /// 28 | public class Decimal128ToDecimalConverter : Decimal128DecimalConverter 29 | { 30 | /// 31 | /// Creates a new instance of the class. 32 | /// 33 | public Decimal128ToDecimalConverter() 34 | : this(null) 35 | { 36 | } 37 | 38 | /// 39 | /// Creates a new instance of the class. 40 | /// 41 | /// 42 | /// Hints that can be used by the to create data types with appropriate 43 | /// facets for the converted data. 44 | /// 45 | public Decimal128ToDecimalConverter(ConverterMappingHints? mappingHints = null) 46 | : base( 47 | ConvertToDecimal(), 48 | ConvertToDecimal128(), 49 | mappingHints) 50 | { 51 | } 52 | 53 | /// 54 | /// A for the default use of this converter. 55 | /// 56 | public static ValueConverterInfo DefaultInfo { get; } 57 | = new(typeof(string), typeof(ObjectId), i => new Decimal128ToDecimalConverter(i.MappingHints)); 58 | } 59 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Storage/ValueConversion/DecimalToDecimal128Converter.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Storage; 17 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 18 | using MongoDB.Bson; 19 | 20 | namespace MongoDB.EntityFrameworkCore.Storage.ValueConversion; 21 | 22 | /// 23 | /// Converts a to and from values. 24 | /// 25 | /// 26 | /// See EF Core value converters for more information and examples. 27 | /// 28 | public class DecimalToDecimal128Converter : Decimal128DecimalConverter 29 | { 30 | /// 31 | /// Creates a new instance of the class. 32 | /// 33 | public DecimalToDecimal128Converter() 34 | : this(null) 35 | { 36 | } 37 | 38 | /// 39 | /// Creates a new instance of the class. 40 | /// 41 | /// 42 | /// Hints that can be used by the to create data types with appropriate 43 | /// facets for the converted data. 44 | /// 45 | public DecimalToDecimal128Converter(ConverterMappingHints? mappingHints = null) 46 | : base( 47 | ConvertToDecimal128(), 48 | ConvertToDecimal(), 49 | mappingHints) 50 | { 51 | } 52 | 53 | /// 54 | /// A for the default use of this converter. 55 | /// 56 | public static ValueConverterInfo DefaultInfo { get; } 57 | = new(typeof(string), typeof(ObjectId), i => new DecimalToDecimal128Converter(i.MappingHints)); 58 | } 59 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Storage/ValueConversion/ObjectIdToStringConverter.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Storage; 17 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 18 | using MongoDB.Bson; 19 | 20 | namespace MongoDB.EntityFrameworkCore.Storage.ValueConversion; 21 | 22 | /// 23 | /// Converts a to and from values. 24 | /// 25 | /// 26 | /// See EF Core value converters for more information and examples. 27 | /// 28 | public class ObjectIdToStringConverter : StringObjectIdConverter 29 | { 30 | /// 31 | /// Creates a new instance of the class. 32 | /// 33 | public ObjectIdToStringConverter() 34 | : this(null) 35 | { 36 | } 37 | 38 | /// 39 | /// Creates a new instance of the class. 40 | /// 41 | /// 42 | /// Hints that can be used by the to create data types with appropriate 43 | /// facets for the converted data. 44 | /// 45 | public ObjectIdToStringConverter(ConverterMappingHints? mappingHints = null) 46 | : base( 47 | ConvertToString(), 48 | ConvertToObjectId(), 49 | mappingHints) 50 | { 51 | } 52 | 53 | /// 54 | /// A for the default use of this converter. 55 | /// 56 | public static ValueConverterInfo DefaultInfo { get; } 57 | = new(typeof(ObjectId), typeof(string), i => new ObjectIdToStringConverter(i.MappingHints)); 58 | } 59 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/Storage/ValueConversion/StringToObjectIdConverter.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.Storage; 17 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 18 | using MongoDB.Bson; 19 | 20 | namespace MongoDB.EntityFrameworkCore.Storage.ValueConversion; 21 | 22 | /// 23 | /// Converts a to and from values. 24 | /// 25 | /// 26 | /// See EF Core value converters for more information and examples. 27 | /// 28 | public class StringToObjectIdConverter : StringObjectIdConverter 29 | { 30 | /// 31 | /// Creates a new instance of the class. 32 | /// 33 | public StringToObjectIdConverter() 34 | : this(null) 35 | { 36 | } 37 | 38 | /// 39 | /// Creates a new instance of the class. 40 | /// 41 | /// 42 | /// Hints that can be used by the to create data types with appropriate 43 | /// facets for the converted data. 44 | /// 45 | public StringToObjectIdConverter(ConverterMappingHints? mappingHints = null) 46 | : base( 47 | ConvertToObjectId(), 48 | ConvertToString(), 49 | mappingHints) 50 | { 51 | } 52 | 53 | /// 54 | /// A for the default use of this converter. 55 | /// 56 | public static ValueConverterInfo DefaultInfo { get; } 57 | = new(typeof(string), typeof(ObjectId), i => new StringToObjectIdConverter(i.MappingHints)); 58 | } 59 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/ValueGeneration/MongoValueGeneratorSelector.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System; 17 | using Microsoft.EntityFrameworkCore; 18 | using Microsoft.EntityFrameworkCore.Metadata; 19 | using Microsoft.EntityFrameworkCore.ValueGeneration; 20 | using MongoDB.Bson; 21 | 22 | namespace MongoDB.EntityFrameworkCore.ValueGeneration; 23 | 24 | /// 25 | /// Implements adding temporary ID 26 | /// functionality for owned entity collections. 27 | /// 28 | public class MongoValueGeneratorSelector : ValueGeneratorSelector 29 | { 30 | /// 31 | /// Create a new . 32 | /// 33 | /// The to use. 34 | public MongoValueGeneratorSelector(ValueGeneratorSelectorDependencies dependencies) 35 | : base(dependencies) 36 | { 37 | } 38 | 39 | /// 40 | protected override ValueGenerator? FindForType(IProperty property, ITypeBase typeBase, Type clrType) 41 | { 42 | // Required to ensure we generate unique IDs for owned entity collections 43 | if (typeBase.ContainingEntityType.IsOwned() && property.IsOwnedCollectionShadowKey()) 44 | { 45 | return new TemporaryNumberValueGeneratorFactory().Create(property, typeBase); 46 | } 47 | 48 | // Allow ObjectId's to be automatically generated 49 | if (clrType == typeof(ObjectId)) 50 | { 51 | return new ObjectIdValueGenerator(); 52 | } 53 | 54 | // Allow strings stored as ObjectId's to be generated too 55 | if (clrType == typeof(string) && IsStoredAsObjectId(property)) 56 | { 57 | return new StringObjectIdValueGenerator(); 58 | } 59 | 60 | return base.FindForType(property, typeBase, clrType); 61 | } 62 | 63 | private static bool IsStoredAsObjectId(IProperty property) 64 | => property.GetValueConverter() is { } converter && converter.ModelClrType == typeof(ObjectId) 65 | || property.GetBsonRepresentation() is {BsonType: BsonType.ObjectId}; 66 | } 67 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/ValueGeneration/ObjectIdValueGenerator.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.ChangeTracking; 17 | using Microsoft.EntityFrameworkCore.ValueGeneration; 18 | using MongoDB.Bson; 19 | 20 | namespace MongoDB.EntityFrameworkCore.ValueGeneration; 21 | 22 | /// 23 | /// Generates unique values. This is the default generator 24 | /// for MongoDB `_id` fields. These generated values persist 25 | /// to the server instead of using server-generated values and round-tripping. 26 | /// 27 | public class ObjectIdValueGenerator : ValueGenerator 28 | { 29 | /// 30 | /// Generates a unique . 31 | /// 32 | /// The this 33 | /// will be used by. 34 | /// A unique . 35 | public override ObjectId Next(EntityEntry entry) 36 | => ObjectId.GenerateNewId(); 37 | 38 | /// 39 | /// Always as this generator is only used for permanent values. 40 | /// 41 | public override bool GeneratesTemporaryValues 42 | => false; 43 | } 44 | -------------------------------------------------------------------------------- /src/MongoDB.EntityFrameworkCore/ValueGeneration/StringObjectIdValueGenerator.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore.ChangeTracking; 17 | using Microsoft.EntityFrameworkCore.ValueGeneration; 18 | using MongoDB.Bson; 19 | 20 | namespace MongoDB.EntityFrameworkCore.ValueGeneration; 21 | 22 | /// 23 | /// Generates unique values. This is the default generator 24 | /// for strings properties mapped to elements. 25 | /// 26 | public class StringObjectIdValueGenerator : ValueGenerator 27 | { 28 | /// 29 | /// Generates a unique as a string. 30 | /// 31 | /// The this 32 | /// as a string will be used by. 33 | /// A unique . 34 | public override string Next(EntityEntry entry) 35 | => ObjectId.GenerateNewId().ToString(); 36 | 37 | /// 38 | /// Always as this generator is only used for permanent values. 39 | /// 40 | public override bool GeneratesTemporaryValues 41 | => false; 42 | } 43 | -------------------------------------------------------------------------------- /tests/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | net8.0 4 | enable 5 | enable 6 | false 7 | true 8 | EF1001,CS8602,CS8618 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | all 18 | 19 | 20 | runtime; build; native; contentfiles; analyzers; buildtransitive 21 | all 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Design/Generated/EF8/SimpleContextModel.cs: -------------------------------------------------------------------------------- 1 | // 2 | using Microsoft.EntityFrameworkCore.Infrastructure; 3 | using Microsoft.EntityFrameworkCore.Metadata; 4 | 5 | #pragma warning disable 219, 612, 618 6 | #nullable disable 7 | 8 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Design 9 | { 10 | [DbContext(typeof(CompiledModelTests.SimpleContext))] 11 | public partial class SimpleContextModel : RuntimeModel 12 | { 13 | private static readonly bool _useOldBehavior31751 = 14 | System.AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31751", out var enabled31751) && enabled31751; 15 | 16 | static SimpleContextModel() 17 | { 18 | var model = new SimpleContextModel(); 19 | 20 | if (_useOldBehavior31751) 21 | { 22 | model.Initialize(); 23 | } 24 | else 25 | { 26 | var thread = new System.Threading.Thread(RunInitialization, 10 * 1024 * 1024); 27 | thread.Start(); 28 | thread.Join(); 29 | 30 | void RunInitialization() 31 | { 32 | model.Initialize(); 33 | } 34 | } 35 | 36 | model.Customize(); 37 | _instance = model; 38 | } 39 | 40 | private static SimpleContextModel _instance; 41 | public static IModel Instance => _instance; 42 | 43 | partial void Initialize(); 44 | 45 | partial void Customize(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Design/Generated/EF8/SimpleContextModelBuilder.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | 6 | #pragma warning disable 219, 612, 618 7 | #nullable disable 8 | 9 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Design 10 | { 11 | public partial class SimpleContextModel 12 | { 13 | partial void Initialize() 14 | { 15 | var everyType = EveryTypeEntityType.Create(this); 16 | var ownedEntity = OwnedEntityEntityType.Create(this); 17 | 18 | OwnedEntityEntityType.CreateForeignKey1(ownedEntity, everyType); 19 | 20 | EveryTypeEntityType.CreateAnnotations(everyType); 21 | OwnedEntityEntityType.CreateAnnotations(ownedEntity); 22 | 23 | AddAnnotation("ProductVersion", "8.0.15"); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Design/Generated/EF9/SimpleContextAssemblyAttributes.cs: -------------------------------------------------------------------------------- 1 | // 2 | using Microsoft.EntityFrameworkCore.Infrastructure; 3 | using MongoDB.EntityFrameworkCore.FunctionalTests.Design; 4 | 5 | #pragma warning disable 219, 612, 618 6 | #nullable disable 7 | 8 | [assembly: DbContextModel(typeof(CompiledModelTests.SimpleContext), typeof(SimpleContextModel))] 9 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Design/Generated/EF9/SimpleContextModel.cs: -------------------------------------------------------------------------------- 1 | // 2 | using Microsoft.EntityFrameworkCore.Infrastructure; 3 | using Microsoft.EntityFrameworkCore.Metadata; 4 | 5 | #pragma warning disable 219, 612, 618 6 | #nullable disable 7 | 8 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Design 9 | { 10 | [DbContext(typeof(CompiledModelTests.SimpleContext))] 11 | public partial class SimpleContextModel : RuntimeModel 12 | { 13 | private static readonly bool _useOldBehavior31751 = 14 | System.AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31751", out var enabled31751) && enabled31751; 15 | 16 | static SimpleContextModel() 17 | { 18 | var model = new SimpleContextModel(); 19 | 20 | if (_useOldBehavior31751) 21 | { 22 | model.Initialize(); 23 | } 24 | else 25 | { 26 | var thread = new System.Threading.Thread(RunInitialization, 10 * 1024 * 1024); 27 | thread.Start(); 28 | thread.Join(); 29 | 30 | void RunInitialization() 31 | { 32 | model.Initialize(); 33 | } 34 | } 35 | 36 | model.Customize(); 37 | _instance = (SimpleContextModel)model.FinalizeModel(); 38 | } 39 | 40 | private static SimpleContextModel _instance; 41 | public static IModel Instance => _instance; 42 | 43 | partial void Initialize(); 44 | 45 | partial void Customize(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Design/Generated/EF9/SimpleContextModelBuilder.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | 6 | #pragma warning disable 219, 612, 618 7 | #nullable disable 8 | 9 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Design 10 | { 11 | public partial class SimpleContextModel 12 | { 13 | private SimpleContextModel() 14 | : base(skipDetectChanges: false, modelId: new Guid("d897c2fe-5214-4c67-842d-a5113b84a740"), entityTypeCount: 2) 15 | { 16 | } 17 | 18 | partial void Initialize() 19 | { 20 | var everyType = EveryTypeEntityType.Create(this); 21 | var ownedEntity = OwnedEntityEntityType.Create(this); 22 | 23 | OwnedEntityEntityType.CreateForeignKey1(ownedEntity, everyType); 24 | 25 | EveryTypeEntityType.CreateAnnotations(everyType); 26 | OwnedEntityEntityType.CreateAnnotations(ownedEntity); 27 | 28 | AddAnnotation("ProductVersion", "9.0.4"); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Entities/Guides/GuidesDbContext.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Diagnostics; 18 | using Microsoft.Extensions.Logging; 19 | using MongoDB.Driver; 20 | using MongoDB.EntityFrameworkCore.Extensions; 21 | 22 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Entities.Guides; 23 | 24 | internal class GuidesDbContext(DbContextOptions options) 25 | : DbContext(options) 26 | { 27 | public DbSet Moons { get; init; } 28 | public DbSet Planets { get; init; } 29 | 30 | public static GuidesDbContext Create( 31 | IMongoDatabase database, 32 | Action? logAction = null, 33 | ILoggerFactory? loggerFactory = null, 34 | bool sensitiveDataLogging = true) => 35 | new(new DbContextOptionsBuilder() 36 | .UseMongoDB(database.Client, database.DatabaseNamespace.DatabaseName) 37 | .ConfigureWarnings(x => x.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)) 38 | .LogTo(l => logAction?.Invoke(l)) 39 | .UseLoggerFactory(loggerFactory) 40 | .EnableSensitiveDataLogging(sensitiveDataLogging) 41 | .Options); 42 | 43 | protected override void OnModelCreating(ModelBuilder modelBuilder) 44 | { 45 | base.OnModelCreating(modelBuilder); 46 | modelBuilder.Entity() 47 | .ToCollection("moons") 48 | .HasKey(nameof(Moon.planetId), nameof(Moon.label)); 49 | modelBuilder.Entity().ToCollection("planets"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Entities/Guides/Planet.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using MongoDB.Bson; 17 | 18 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Entities.Guides; 19 | 20 | #nullable disable 21 | 22 | internal class Planet 23 | { 24 | public ObjectId _id { get; set; } 25 | public string name { get; set; } 26 | public int orderFromSun { get; set; } 27 | public bool hasRings { get; set; } 28 | public string[] mainAtmosphere { get; set; } 29 | } 30 | 31 | internal class Moon 32 | { 33 | public ObjectId planetId { get; set; } 34 | public string label { get; set; } 35 | public string name { get; set; } 36 | public int? yearOfDiscovery { get; set; } 37 | } 38 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Metadata/Conventions/BsonAttributes/BsonIgnoreAttributeConventionTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using MongoDB.Bson; 17 | using MongoDB.Bson.Serialization.Attributes; 18 | using MongoDB.Driver; 19 | 20 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Metadata.Conventions.BsonAttributes; 21 | 22 | [XUnitCollection("ConventionsTests")] 23 | public class BsonIgnoreAttributeConventionTests(TemporaryDatabaseFixture database) 24 | : IClassFixture 25 | { 26 | class IgnoredPropertiesEntity 27 | { 28 | public ObjectId _id { get; set; } 29 | 30 | public string? KeepMe { get; set; } 31 | 32 | [BsonIgnore] 33 | public string? IgnoreMe { get; set; } 34 | 35 | [BsonIgnore] 36 | public bool AndMe { get; set; } 37 | } 38 | 39 | class PropertiesEntity 40 | { 41 | public ObjectId _id { get; set; } 42 | 43 | public string? KeepMe { get; set; } 44 | 45 | public string? IgnoreMe { get; set; } 46 | 47 | public bool AndMe { get; set; } 48 | } 49 | 50 | [Fact] 51 | public void BsonElementAttribute_redefines_element_name_for_insert_and_query() 52 | { 53 | var collection = database.CreateCollection(); 54 | 55 | var id = ObjectId.GenerateNewId(); 56 | const string name = "The quick brown fox"; 57 | 58 | { 59 | using var db = SingleEntityDbContext.Create(collection); 60 | db.Entities.Add(new IgnoredPropertiesEntity {_id = id, KeepMe = name, IgnoreMe = "a", AndMe = true}); 61 | db.SaveChanges(); 62 | } 63 | 64 | { 65 | var actual = collection.Database.GetCollection(collection.CollectionNamespace.CollectionName); 66 | var directFound = actual.Find(f => f._id == id).Single(); 67 | Assert.Equal(name, directFound.KeepMe); 68 | Assert.Null(directFound.IgnoreMe); 69 | Assert.False(directFound.AndMe); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/MongoDB.EntityFrameworkCore.FunctionalTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Debug;Release;Debug EF9;Release EF9 4 | AnyCPU 5 | 6 | 7 | TRACE;DEBUG;EF9 8 | 9 | 10 | TRACE;RELEASE;EF9 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | <_Parameter1>XUnit.Startup.Dispose.Hooks.TestFramework 34 | <_Parameter2>XUnit.Startup.Dispose.Hooks 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Query/CollectionsResponseTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using MongoDB.EntityFrameworkCore.FunctionalTests.Entities.Guides; 18 | 19 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Query; 20 | 21 | [XUnitCollection(nameof(ReadOnlySampleGuidesFixture))] 22 | public class CollectionsResponseTests(ReadOnlySampleGuidesFixture database) 23 | : IDisposable, IAsyncDisposable 24 | { 25 | private readonly GuidesDbContext _db = GuidesDbContext.Create(database.MongoDatabase); 26 | 27 | [Fact] 28 | public void ToList() 29 | { 30 | var result = _db.Planets.ToList(); 31 | Assert.Equal(8, result.Count); 32 | } 33 | 34 | [Fact] 35 | public async Task ToListAsync() 36 | { 37 | var result = await _db.Planets.ToListAsync(); 38 | Assert.Equal(8, result.Count); 39 | } 40 | 41 | [Fact] 42 | public void ToArray() 43 | { 44 | var result = _db.Planets.ToArray(); 45 | Assert.Equal(8, result.Length); 46 | } 47 | 48 | [Fact] 49 | public async Task ToArrayAsync() 50 | { 51 | var result = await _db.Planets.ToArrayAsync(); 52 | Assert.Equal(8, result.Length); 53 | } 54 | 55 | public void Dispose() 56 | => _db.Dispose(); 57 | 58 | public async ValueTask DisposeAsync() 59 | => await _db.DisposeAsync(); 60 | } 61 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Query/InvalidQueryTranslationTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Linq.Expressions; 17 | using System.Reflection; 18 | 19 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Query; 20 | 21 | [XUnitCollection("QueryTests")] 22 | public class InvalidQueryTranslationTests(TemporaryDatabaseFixture database) 23 | : IClassFixture 24 | { 25 | class SimpleEntity 26 | { 27 | public Guid _id { get; set; } 28 | public string name { get; set; } 29 | } 30 | 31 | [Fact] 32 | public void ExecuteDelete_throws_invalid_operation_exception() 33 | { 34 | using var db = SingleEntityDbContext.Create(database.CreateCollection()); 35 | 36 | var ex = Assert.Throws(() => db.Entities.ExecuteDelete()); 37 | Assert.Contains("ExecuteDelete", ex.Message); 38 | Assert.Contains("LINQ expression", ex.Message); 39 | } 40 | } 41 | 42 | static class FakeQueryableExtensions 43 | { 44 | internal static int ExecuteDelete(this IQueryable source) 45 | => source.Provider.Execute(Expression.Call(ExecuteDeleteMethodInfo.MakeGenericMethod(typeof(TSource)), 46 | source.Expression)); 47 | 48 | private static readonly MethodInfo ExecuteDeleteMethodInfo 49 | = typeof(FakeQueryableExtensions).GetTypeInfo().GetDeclaredMethod(nameof(ExecuteDelete))!; 50 | } 51 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Query/TopSetTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using MongoDB.EntityFrameworkCore.FunctionalTests.Entities.Guides; 17 | 18 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Query; 19 | 20 | [XUnitCollection(nameof(ReadOnlySampleGuidesFixture))] 21 | public sealed class TopSetTests(ReadOnlySampleGuidesFixture database) 22 | : IDisposable, IAsyncDisposable 23 | { 24 | private readonly GuidesDbContext _db = GuidesDbContext.Create(database.MongoDatabase); 25 | 26 | [Fact] 27 | public void Cast_to_parent() 28 | { 29 | var all = _db.Planets.Cast().ToList(); 30 | 31 | Assert.Equal(8, all.Count); 32 | } 33 | 34 | [Theory] 35 | [InlineData(true)] 36 | [InlineData(false)] 37 | public void Concat(bool overlap) 38 | { 39 | var a = _db.Planets.Take(3); 40 | var b = _db.Planets.Skip(overlap ? 2 : 3).Take(2); 41 | 42 | var union = a.Concat(b).ToList(); 43 | 44 | Assert.Equal(5, union.Count); 45 | } 46 | 47 | [Theory] 48 | [InlineData(true)] 49 | [InlineData(false)] 50 | public void Distinct(bool overlap) 51 | { 52 | var a = _db.Planets.Take(3); 53 | var b = _db.Planets.Skip(overlap ? 2 : 3).Take(2); 54 | 55 | var union = a.Concat(b).Distinct().ToList(); 56 | 57 | Assert.Equal(overlap ? 4 : 5, union.Count); 58 | } 59 | 60 | [Theory] 61 | [InlineData(true)] 62 | [InlineData(false)] 63 | public void Union(bool overlap) 64 | { 65 | var source1 = _db.Planets.Take(3); 66 | var source2 = _db.Planets.Skip(overlap ? 2 : 3).Take(2); 67 | 68 | var union = source1.Union(source2).ToList(); 69 | 70 | Assert.Equal(overlap ? 4 : 5, union.Count); 71 | } 72 | 73 | public void Dispose() 74 | => _db.Dispose(); 75 | 76 | public async ValueTask DisposeAsync() 77 | => await _db.DisposeAsync(); 78 | } 79 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Serialization/BaseSerializationTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Runtime.CompilerServices; 17 | using MongoDB.Bson; 18 | using MongoDB.Driver; 19 | 20 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Serialization; 21 | 22 | [XUnitCollection("SerializationTests")] 23 | public abstract class BaseSerializationTests(TemporaryDatabaseFixture database) 24 | : IClassFixture 25 | { 26 | protected readonly TemporaryDatabaseFixture Database = database; 27 | 28 | protected class BaseIdEntity 29 | { 30 | public ObjectId id { get; set; } 31 | } 32 | 33 | protected IMongoCollection SetupIdOnlyCollection([CallerMemberName] string? methodName = null) 34 | { 35 | var collection = Database.CreateCollection(methodName); 36 | collection.WriteTestDocs(new[] {new BaseIdEntity()}); 37 | return Database.GetCollection(collection.CollectionNamespace); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Storage/TransactionTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Storage; 17 | 18 | [XUnitCollection("StorageTests")] 19 | public class TransactionTests(TemporaryDatabaseFixture database) 20 | : IClassFixture 21 | { 22 | class SimpleEntity 23 | { 24 | public Guid _id { get; set; } 25 | public string name { get; set; } 26 | } 27 | 28 | [Fact] 29 | public void MongoTransactionManager_throws_if_transaction_attempted() 30 | { 31 | using var db = SingleEntityDbContext.Create(database.CreateCollection()); 32 | 33 | var ex = Assert.Throws(() => db.Database.BeginTransaction()); 34 | Assert.Contains("does not support transactions", ex.Message); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/TestInitialization.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Runtime.CompilerServices; 17 | 18 | namespace MongoDB.EntityFrameworkCore.FunctionalTests; 19 | 20 | public class TestInitialization 21 | { 22 | [ModuleInitializer] 23 | public static void CleanDatabase() 24 | { 25 | var client = TestServer.GetClient(); 26 | var databaseNameCursor = client.ListDatabaseNames(); 27 | while (databaseNameCursor.MoveNext()) 28 | { 29 | foreach (var databaseName in databaseNameCursor.Current) 30 | { 31 | if (databaseName.StartsWith(TemporaryDatabaseFixture.TestDatabasePrefix)) 32 | client.DropDatabase(databaseName); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Usings.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | global using Xunit; 17 | global using XUnitCollection = Xunit.CollectionAttribute; 18 | global using MongoDB.EntityFrameworkCore.FunctionalTests.Utilities; 19 | 20 | [assembly:CollectionBehavior(DisableTestParallelization = true)] 21 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Utilities/EnumerableOnlyWrapper.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Collections; 17 | 18 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Utilities; 19 | 20 | internal static class EnumerableOnlyWrapper 21 | { 22 | public static EnumerableOnlyWrapper Wrap(IEnumerable source) 23 | => new(source); 24 | } 25 | 26 | internal class EnumerableOnlyWrapper(IEnumerable source) : IEnumerable 27 | { 28 | public IEnumerator GetEnumerator() => source.GetEnumerator(); 29 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 30 | } 31 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Utilities/ExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using MongoDB.Bson; 17 | using MongoDB.Driver; 18 | 19 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Utilities; 20 | 21 | internal static class ExtensionMethods 22 | { 23 | private static int NextInt32(this Random random) 24 | => random.Next(0, 1 << 4) << 28 | random.Next(0, 1 << 28); 25 | 26 | // From John Skeet's answer at https://stackoverflow.com/questions/609501/generating-a-random-decimal-in-c-sharp 27 | public static decimal NextDecimal(this Random random) 28 | => new(random.NextInt32(), 29 | random.NextInt32(), 30 | random.NextInt32(), 31 | random.Next(2) == 1, 32 | (byte)random.Next(29)); 33 | 34 | public static byte NextByte(this Random random) 35 | => (byte)random.Next(0, byte.MaxValue); 36 | 37 | public static short NextInt16(this Random random) 38 | => (short)random.Next(1, short.MaxValue); 39 | 40 | public static void WriteTestDocs(this IMongoCollection collection, IEnumerable docs) 41 | => collection.BulkWrite(docs.Select(p => new InsertOneModel(p))); 42 | 43 | public static DateTime ToBsonPrecision(this DateTime dateTime) 44 | { 45 | var bsonDateTime = new BsonDateTime(dateTime); 46 | return dateTime.Kind == DateTimeKind.Utc ? bsonDateTime.ToUniversalTime() : bsonDateTime.ToLocalTime(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Utilities/NamedContainer.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Utilities; 17 | 18 | internal class NamedContainer 19 | { 20 | public T? Item { get; set; } 21 | 22 | public NamedContainer() 23 | { 24 | } 25 | 26 | public NamedContainer(T item) 27 | { 28 | Item = item; 29 | } 30 | 31 | public NamedContainer(T item, string name) 32 | { 33 | Item = item; 34 | Name = name; 35 | } 36 | 37 | public string? Name { get; set; } 38 | } 39 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Utilities/ReadOnlySampleGuidesFixture.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using MongoDB.Driver; 17 | 18 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Utilities; 19 | 20 | [CollectionDefinition(nameof(ReadOnlySampleGuidesFixture))] 21 | public class ReadOnlySampleGuidesFixtureCollection : ICollectionFixture 22 | { 23 | // This class has no code, and is never created. Its purpose is simply 24 | // to be the place to apply [CollectionDefinition] and all the 25 | // ICollectionFixture<> interfaces. 26 | } 27 | 28 | public class ReadOnlySampleGuidesFixture 29 | { 30 | public ReadOnlySampleGuidesFixture() 31 | { 32 | Client = TestServer.GetClient(); 33 | MongoDatabase = Client.GetDatabase("EFCoreTest-SampleGuides"); 34 | SampleGuides.Populate(MongoDatabase); 35 | } 36 | 37 | public IMongoDatabase MongoDatabase { get; } 38 | public IMongoClient Client { get; } 39 | } 40 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Utilities/SampleGuidesFixture.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Utilities; 17 | 18 | [CollectionDefinition(nameof(SampleGuidesFixture))] 19 | public class SampleGuidesFixtureCollection : ICollectionFixture 20 | { 21 | // This class has no code, and is never created. Its purpose is simply 22 | // to be the place to apply [CollectionDefinition] and all the 23 | // ICollectionFixture<> interfaces. 24 | } 25 | 26 | public class SampleGuidesFixture : TemporaryDatabaseFixture 27 | { 28 | public SampleGuidesFixture() 29 | { 30 | SampleGuides.Populate(MongoDatabase); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Utilities/SpyLogging.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Collections.Concurrent; 17 | using Microsoft.Extensions.Logging; 18 | 19 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Utilities; 20 | 21 | internal class SpyLoggerProvider : ILoggerProvider 22 | { 23 | public static (LoggerFactory, SpyLoggerProvider) Create() 24 | { 25 | var loggerFactory = new LoggerFactory(); 26 | var spyLogger = new SpyLoggerProvider(); 27 | loggerFactory.AddProvider(spyLogger); 28 | return (loggerFactory, spyLogger); 29 | } 30 | 31 | public readonly ConcurrentDictionary Loggers = []; 32 | 33 | public void Dispose() 34 | { 35 | } 36 | 37 | public ILogger CreateLogger(string categoryName) 38 | => Loggers.GetOrAdd(categoryName, _ => new SpyLogger()); 39 | } 40 | 41 | internal class SpyLogger : ILogger 42 | { 43 | public readonly List Records = []; 44 | 45 | public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, 46 | Func formatter) 47 | => Records.Add(new SpyLogRecord(logLevel, eventId, formatter(state, exception) , exception)); 48 | 49 | public bool IsEnabled(LogLevel logLevel) 50 | => true; 51 | 52 | public IDisposable BeginScope(TState state) where TState : notnull 53 | => throw new NotImplementedException(); 54 | } 55 | 56 | internal record SpyLogRecord(LogLevel LogLevel, EventId EventId, string message, Exception? Exception); 57 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.FunctionalTests/Utilities/TestServer.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using MongoDB.Driver; 17 | 18 | namespace MongoDB.EntityFrameworkCore.FunctionalTests.Utilities; 19 | 20 | internal static class TestServer 21 | { 22 | public static readonly string ConnectionString = Environment.GetEnvironmentVariable("MONGODB_URI") ?? "mongodb://localhost:27017"; 23 | private static readonly MongoClient MongoClient = new(ConnectionString); 24 | 25 | public static IMongoClient GetClient() 26 | => MongoClient; 27 | 28 | public static readonly IMongoClient BrokenClient 29 | = new MongoClient(new MongoClientSettings { Server = new MongoServerAddress("localhost", 27000), ServerSelectionTimeout = TimeSpan.Zero, ConnectTimeout = TimeSpan.FromSeconds(1)}); 30 | } 31 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/Infrastructure/MongoOptionsExtensionTest.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using MongoDB.Driver; 18 | 19 | namespace MongoDB.EntityFrameworkCore.UnitTests.Infrastructure; 20 | 21 | public static class MongoOptionsExtensionTest 22 | { 23 | [Fact] 24 | public static void Can_set_connection_string_and_database_name() 25 | { 26 | var dbOptions = new MongoOptionsExtension() 27 | .WithConnectionString("mongodb://localhost:1234") 28 | .WithDatabaseName("MyDatabase"); 29 | 30 | Assert.Equal("mongodb://localhost:1234", dbOptions.ConnectionString); 31 | Assert.Equal("MyDatabase", dbOptions.DatabaseName); 32 | } 33 | 34 | [Theory] 35 | [InlineData("SomeDatabase")] 36 | public static void Can_set_mongo_client_and_database_name(string databaseName) 37 | { 38 | var mongoClient = new MongoClient(); 39 | 40 | var dbOptions = new MongoOptionsExtension() 41 | .WithMongoClient(mongoClient) 42 | .WithDatabaseName(databaseName); 43 | 44 | Assert.Same(mongoClient, dbOptions.MongoClient); 45 | Assert.Equal(databaseName, dbOptions.DatabaseName); 46 | } 47 | 48 | [Fact] 49 | public static void Throws_if_both_connection_string_and_mongo_client_set() 50 | { 51 | Assert.Throws(() => new MongoOptionsExtension() 52 | .WithMongoClient(new MongoClient()) 53 | .WithConnectionString("mongodb://localhost:1234")); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/Metadata/Attributes/CollectionAttributeTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | namespace MongoDB.EntityFrameworkCore.UnitTests.Metadata.Attributes; 17 | 18 | public static class CollectionAttributeTests 19 | { 20 | [Theory] 21 | [InlineData("CollectionNameSet")] 22 | public static void Constructor_name_sets_property(string name) 23 | { 24 | var attribute = new CollectionAttribute(name); 25 | Assert.Equal(name, attribute.Name); 26 | } 27 | 28 | [Theory] 29 | [InlineData(null)] 30 | [InlineData("")] 31 | [InlineData(" \t\r\n")] 32 | public static void Constructor_throws_argument_exception_when_empty(string? name) 33 | { 34 | Assert.Throws(() => new CollectionAttribute(name!)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/Metadata/Conventions/BsonAttributes/BsonElementAttributeConventionTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Diagnostics; 18 | using MongoDB.Bson.Serialization.Attributes; 19 | 20 | namespace MongoDB.EntityFrameworkCore.UnitTests.Metadata.Conventions.BsonAttributes; 21 | 22 | public static class BsonElementAttributeConventionTests 23 | { 24 | [Fact] 25 | public static void BsonElement_specified_names_are_used_as_element_names() 26 | { 27 | using var db = new BaseDbContext(); 28 | Assert.Equal("attributeSpecifiedName", db.GetProperty((Customer c) => c.Name)?.GetElementName()); 29 | } 30 | 31 | [Fact] 32 | public static void ModelBuilder_specified_names_override_BsonElement_names() 33 | { 34 | using var db = new ModelBuilderSpecifiedDbContext(); 35 | Assert.Equal("fluentSpecifiedName", db.GetProperty((Customer c) => c.Name)?.GetElementName()); 36 | } 37 | 38 | class Customer 39 | { 40 | public int Id { get; set; } 41 | 42 | [BsonElement("attributeSpecifiedName")] 43 | public string Name { get; set; } 44 | } 45 | 46 | class BaseDbContext : DbContext 47 | { 48 | public DbSet Customers { get; set; } 49 | 50 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 51 | => optionsBuilder 52 | .UseMongoDB("mongodb://localhost:27017", "UnitTests") 53 | .ConfigureWarnings(x => x.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)); 54 | } 55 | 56 | class ModelBuilderSpecifiedDbContext : BaseDbContext 57 | { 58 | protected override void OnModelCreating(ModelBuilder modelBuilder) 59 | { 60 | base.OnModelCreating(modelBuilder); 61 | modelBuilder.Entity().Property(c => c.Name).HasElementName("fluentSpecifiedName"); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/Metadata/Conventions/BsonAttributes/BsonIgnoreAttributeConventionTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Diagnostics; 18 | using MongoDB.Bson.Serialization.Attributes; 19 | 20 | namespace MongoDB.EntityFrameworkCore.UnitTests.Metadata.Conventions.BsonAttributes; 21 | 22 | public static class BsonIgnoreAttributeConventionTests 23 | { 24 | [Fact] 25 | public static void BsonIgnored_specified_properties_are_unmapped() 26 | { 27 | using var db = new BaseDbContext(); 28 | 29 | var property = db.GetProperty((Customer c) => c.IgnoreMe); 30 | 31 | Assert.Null(property); 32 | } 33 | 34 | [Fact] 35 | public static void ModelBuilder_specified_names_override_BsonIgnored_attribute() 36 | { 37 | using var db = new ModelBuilderSpecifiedDbContext(); 38 | 39 | var property = db.GetProperty((Customer c) => c.IgnoreMe); 40 | 41 | Assert.NotNull(property); 42 | } 43 | 44 | class Customer 45 | { 46 | public int Id { get; set; } 47 | 48 | [BsonIgnore] 49 | public string IgnoreMe { get; set; } 50 | } 51 | 52 | class BaseDbContext : DbContext 53 | { 54 | public DbSet Customers { get; set; } 55 | 56 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 57 | => optionsBuilder 58 | .UseMongoDB("mongodb://localhost:27017", "UnitTests") 59 | .ConfigureWarnings(x => x.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)); 60 | } 61 | 62 | class ModelBuilderSpecifiedDbContext : BaseDbContext 63 | { 64 | protected override void OnModelCreating(ModelBuilder modelBuilder) 65 | { 66 | base.OnModelCreating(modelBuilder); 67 | modelBuilder.Entity().Property(p => p.IgnoreMe).IsRequired(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/Metadata/Conventions/BsonAttributes/BsonRequiredAttributeConventionTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Diagnostics; 18 | using MongoDB.Bson.Serialization.Attributes; 19 | 20 | namespace MongoDB.EntityFrameworkCore.UnitTests.Metadata.Conventions.BsonAttributes; 21 | 22 | public static class BsonRequiredAttributeConventionTests 23 | { 24 | [Fact] 25 | public static void BsonRequired_specified_properties_are_required() 26 | { 27 | using var db = new BaseDbContext(); 28 | 29 | var property = db.GetProperty((Customer c) => c.RequireMe); 30 | 31 | Assert.False(property?.IsNullable); 32 | } 33 | 34 | [Fact] 35 | public static void ModelBuilder_specified_not_required_override_BsonRequired_attribute() 36 | { 37 | using var db = new ModelBuilderSpecifiedDbContext(); 38 | 39 | var property = db.GetProperty((Customer c) => c.RequireMe); 40 | 41 | Assert.True(property?.IsNullable); 42 | } 43 | 44 | class Customer 45 | { 46 | public int Id { get; set; } 47 | 48 | [BsonRequired] 49 | public string RequireMe { get; set; } 50 | } 51 | 52 | class BaseDbContext : DbContext 53 | { 54 | public DbSet Customers { get; set; } 55 | 56 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 57 | => optionsBuilder 58 | .UseMongoDB("mongodb://localhost:27017", "UnitTests") 59 | .ConfigureWarnings(x => x.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)); 60 | } 61 | 62 | class ModelBuilderSpecifiedDbContext : BaseDbContext 63 | { 64 | protected override void OnModelCreating(ModelBuilder modelBuilder) 65 | { 66 | base.OnModelCreating(modelBuilder); 67 | modelBuilder.Entity().Property(p => p.RequireMe).IsRequired(false); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/Metadata/Conventions/CollectionAttributeConventionTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Diagnostics; 18 | using MongoDB.EntityFrameworkCore.Extensions; 19 | 20 | namespace MongoDB.EntityFrameworkCore.UnitTests.Metadata.Conventions; 21 | 22 | public static class CollectionAttributeConventionTests 23 | { 24 | [Fact] 25 | public static void Collection_attribute_specified_names_are_used_as_collection_names() 26 | { 27 | using var db = new BaseDbContext(); 28 | Assert.Equal("attributedCollection", db.GetCollectionName()); 29 | } 30 | 31 | [Fact] 32 | public static void Model_builder_specified_names_override_collection_attribute_names() 33 | { 34 | using var db = new ModelBuilderSpecifiedDbContext(); 35 | Assert.Equal("namedCollection", db.GetCollectionName()); 36 | } 37 | 38 | [Collection("attributedCollection")] 39 | class Customer 40 | { 41 | public int Id { get; set; } 42 | public string Name { get; set; } 43 | } 44 | 45 | class BaseDbContext : DbContext 46 | { 47 | public DbSet Customers { get; set; } 48 | 49 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 50 | => optionsBuilder 51 | .UseMongoDB("mongodb://localhost:27017", "UnitTests") 52 | .ConfigureWarnings(x => x.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)); 53 | } 54 | 55 | class ModelBuilderSpecifiedDbContext : BaseDbContext 56 | { 57 | protected override void OnModelCreating(ModelBuilder modelBuilder) 58 | { 59 | base.OnModelCreating(modelBuilder); 60 | modelBuilder.Entity().ToCollection("namedCollection"); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/Metadata/Conventions/CollectionNameFromDbSetConventionTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Diagnostics; 18 | using MongoDB.EntityFrameworkCore.Extensions; 19 | 20 | namespace MongoDB.EntityFrameworkCore.UnitTests.Metadata.Conventions; 21 | 22 | public static class CollectionNameFromDbSetConventionTests 23 | { 24 | [Fact] 25 | public static void DbSet_names_are_used_as_collection_names() 26 | { 27 | using var db = new UnnamedCollectionsDbContext(); 28 | Assert.Equal("Customers", db.GetCollectionName()); 29 | } 30 | 31 | [Fact] 32 | public static void Explicit_collection_names_can_be_set() 33 | { 34 | using var db = new NamedCollectionsDbContext(); 35 | Assert.Equal("customersCollection", db.GetCollectionName()); 36 | } 37 | 38 | class Customer 39 | { 40 | public int Id { get; set; } 41 | public string Name { get; set; } 42 | } 43 | 44 | abstract class BaseDbContext : DbContext 45 | { 46 | public DbSet Customers { get; set; } 47 | } 48 | 49 | class UnnamedCollectionsDbContext : BaseDbContext 50 | { 51 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 52 | => optionsBuilder 53 | .UseMongoDB("mongodb://localhost:27017", "UnitTests") 54 | .ConfigureWarnings(x => x.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)); 55 | } 56 | 57 | class NamedCollectionsDbContext : BaseDbContext 58 | { 59 | protected override void OnModelCreating(ModelBuilder modelBuilder) 60 | { 61 | base.OnModelCreating(modelBuilder); 62 | modelBuilder.Entity().ToCollection("customersCollection"); 63 | } 64 | 65 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 66 | => optionsBuilder 67 | .UseMongoDB("mongodb://localhost:27017", "UnitTests") 68 | .ConfigureWarnings(x => x.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/Metadata/Conventions/DateTimeKindConventionTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using MongoDB.EntityFrameworkCore.Metadata.Conventions; 18 | 19 | namespace MongoDB.EntityFrameworkCore.UnitTests.Metadata.Conventions; 20 | 21 | public class DateTimeKindConventionTests 22 | { 23 | [Theory] 24 | [InlineData(DateTimeKind.Local)] 25 | [InlineData(DateTimeKind.Utc)] 26 | [InlineData(DateTimeKind.Unspecified)] 27 | public static void Can_build_a_model_with_DateTimeKind(DateTimeKind value) 28 | { 29 | var conventions = MongoConventionSetBuilder.Build(); 30 | conventions.Add(new DateTimeKindConvention(value)); 31 | var modelBuilder = new ModelBuilder(conventions); 32 | modelBuilder.Entity(); 33 | 34 | var entity = modelBuilder.Model.FindEntityType(typeof(TestEntity)); 35 | 36 | Assert.Equal(value, entity.GetProperty(nameof(TestEntity.DateTimeProperty)).GetDateTimeKind()); 37 | Assert.Equal(value, entity.GetProperty(nameof(TestEntity.NullableDateTimeProperty)).GetDateTimeKind()); 38 | Assert.Equal(DateTimeKind.Unspecified, entity.GetProperty(nameof(TestEntity.StringProperty)).GetDateTimeKind()); 39 | } 40 | 41 | private class TestEntity 42 | { 43 | public DateTime DateTimeProperty { get; set; } 44 | 45 | public DateTime? NullableDateTimeProperty { get; set; } 46 | 47 | public string StringProperty { get; set; } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/MongoDB.EntityFrameworkCore.UnitTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Debug;Release;Debug EF9;Release EF9 4 | AnyCPU 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/NamingHelperMethodTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Globalization; 17 | 18 | namespace MongoDB.EntityFrameworkCore.UnitTests; 19 | 20 | public static class NamingHelperMethodTests 21 | { 22 | [Theory] 23 | [InlineData("THIS_word", "thisWord")] 24 | [InlineData("ThatWord", "thatWord")] 25 | [InlineData("a-lot-of-wordsHere", "aLotOfWordsHere")] 26 | [InlineData("TESTING", "testing")] 27 | [InlineData("TESTING123a", "testing123A")] 28 | [InlineData("Η θήκη της καμήλας είναι ΚΑΛΗ", "ηΘήκηΤηςΚαμήλαςΕίναιΚαλη")] 29 | [InlineData("IsJSONProperty", "isJsonProperty")] 30 | [InlineData("test-THIS-Out", "testThisOut")] 31 | public static void ToCamelCase_finds_word_boundaries_and_camel_cases_words(string toConvert, string expected) 32 | { 33 | var actual = toConvert.ToCamelCase(CultureInfo.InvariantCulture); 34 | Assert.Equal(expected, actual); 35 | } 36 | 37 | [Theory] 38 | [InlineData("THIS_word", "ThisWord")] 39 | [InlineData("ThatWord", "ThatWord")] 40 | [InlineData("a-lot-of-wordsHere", "ALotOfWordsHere")] 41 | [InlineData("TESTING", "Testing")] 42 | [InlineData("TESTING123a", "Testing123A")] 43 | [InlineData("Η θήκη της καμήλας είναι ΚΑΛΗ", "ΗΘήκηΤηςΚαμήλαςΕίναιΚαλη")] 44 | [InlineData("IsJSONProperty", "IsJsonProperty")] 45 | [InlineData("test-THIS-Out", "TestThisOut")] 46 | public static void ToTitleCase_finds_word_boundaries_and_title_cases_words(string toConvert, string expected) 47 | { 48 | var actual = toConvert.ToTitleCase(CultureInfo.InvariantCulture); 49 | Assert.Equal(expected, actual); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/Query/Expressions/MongoCollectionExpressionTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Diagnostics; 18 | using MongoDB.Bson; 19 | using MongoDB.EntityFrameworkCore.Extensions; 20 | using MongoDB.EntityFrameworkCore.Query.Expressions; 21 | 22 | namespace MongoDB.EntityFrameworkCore.UnitTests.Query.Expressions; 23 | 24 | public static class MongoCollectionExpressionTests 25 | { 26 | class Product 27 | { 28 | public ObjectId Id { get; set; } 29 | public string Name { get; set; } 30 | public decimal Price { get; set; } 31 | } 32 | 33 | class Location 34 | { 35 | public ObjectId Id { get; set; } 36 | public string Title { get; set; } 37 | public double Longitude { get; set; } 38 | public double Latitude { get; set; } 39 | } 40 | 41 | class CollectionDbContext : DbContext 42 | { 43 | public DbSet Products { get; set; } 44 | public DbSet Location { get; set; } 45 | 46 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 47 | => optionsBuilder 48 | .UseMongoDB("mongodb://localhost:27017", "UnitTests") 49 | .ConfigureWarnings(x => x.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)); 50 | } 51 | 52 | [Fact] 53 | public static void Can_set_properties_from_constructor() 54 | { 55 | using var db = new CollectionDbContext(); 56 | 57 | foreach (var entityType in db.Model.GetEntityTypes()) 58 | { 59 | var actual = new MongoCollectionExpression(entityType); 60 | Assert.Equal(entityType, actual.EntityType); 61 | Assert.Equal(entityType.GetCollectionName(), actual.CollectionName); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/Query/Expressions/MongoQueryExpressionTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Diagnostics; 18 | using MongoDB.Bson; 19 | using MongoDB.EntityFrameworkCore.Query.Expressions; 20 | 21 | namespace MongoDB.EntityFrameworkCore.UnitTests.Query.Expressions; 22 | 23 | public static class MongoQueryExpressionTests 24 | { 25 | class Product 26 | { 27 | public ObjectId Id { get; set; } 28 | public string Name { get; set; } 29 | public decimal Price { get; set; } 30 | } 31 | 32 | class QueryDbContext : DbContext 33 | { 34 | public DbSet Products { get; set; } 35 | 36 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 37 | => optionsBuilder 38 | .UseMongoDB("mongodb://localhost:27017", "UnitTests") 39 | .ConfigureWarnings(x => x.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)); 40 | } 41 | 42 | [Fact] 43 | public static void Set_collection_to_entity_passed_in_constructor() 44 | { 45 | using var db = new QueryDbContext(); 46 | var expectedEntityType = db.Model.GetEntityTypes().First(); 47 | 48 | var actual = new MongoQueryExpression(expectedEntityType); 49 | 50 | Assert.Equal(expectedEntityType, actual.CollectionExpression.EntityType); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/Storage/MongoTransactionManagerTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using MongoDB.EntityFrameworkCore.Storage; 17 | 18 | namespace MongoDB.EntityFrameworkCore.UnitTests.Storage; 19 | 20 | public class MongoTransactionManagerTests 21 | { 22 | [Fact] 23 | public async Task Does_not_support_transactions() 24 | { 25 | var transactionManager = new MongoTransactionManager(); 26 | 27 | Assert.Throws(() => transactionManager.BeginTransaction()); 28 | await Assert.ThrowsAsync(async () => await transactionManager.BeginTransactionAsync()); 29 | 30 | Assert.Throws(() => transactionManager.CommitTransaction()); 31 | await Assert.ThrowsAsync(async () => await transactionManager.CommitTransactionAsync()); 32 | 33 | Assert.Throws(() => transactionManager.RollbackTransaction()); 34 | await Assert.ThrowsAsync(async () => await transactionManager.RollbackTransactionAsync()); 35 | 36 | Assert.Null(transactionManager.CurrentTransaction); 37 | Assert.Null(transactionManager.EnlistedTransaction); 38 | 39 | Assert.Throws(() => transactionManager.EnlistTransaction(null)); 40 | 41 | transactionManager.ResetState(); 42 | await transactionManager.ResetStateAsync(); 43 | 44 | Assert.Null(transactionManager.CurrentTransaction); 45 | Assert.Null(transactionManager.EnlistedTransaction); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/TestUtilities/MongoTestHelpers.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Diagnostics; 18 | using Microsoft.EntityFrameworkCore.TestUtilities; 19 | using Microsoft.Extensions.DependencyInjection; 20 | 21 | namespace MongoDB.EntityFrameworkCore.UnitTests.TestUtilities; 22 | 23 | public sealed class MongoTestHelpers : TestHelpers 24 | { 25 | private MongoTestHelpers() 26 | { 27 | } 28 | 29 | public static MongoTestHelpers Instance { get; } = new(); 30 | 31 | public override IServiceCollection AddProviderServices(IServiceCollection services) 32 | => services.AddEntityFrameworkMongoDB(); 33 | 34 | public override DbContextOptionsBuilder UseProviderOptions(DbContextOptionsBuilder optionsBuilder) 35 | => optionsBuilder 36 | .UseMongoDB("mongodb://localhost:27017", "UnitTests") 37 | .ConfigureWarnings(x => x.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)); 38 | } 39 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/TestUtilities/SingleEntityDbContext.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Diagnostics; 18 | using Microsoft.EntityFrameworkCore.Infrastructure; 19 | 20 | namespace MongoDB.EntityFrameworkCore.UnitTests.TestUtilities; 21 | 22 | internal static class SingleEntityDbContext 23 | { 24 | private static DbContextOptions> CreateOptionsBuilder() where T : class 25 | => new DbContextOptionsBuilder>() 26 | .UseMongoDB("mongodb://localhost:27017", "UnitTests") 27 | .ReplaceService() 28 | .ConfigureWarnings(x => x.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning)) 29 | .Options; 30 | 31 | public static SingleEntityDbContext Create(Action? modelBuilderAction = null) where T : class => 32 | new(CreateOptionsBuilder(), modelBuilderAction); 33 | 34 | private sealed class IgnoreCacheKeyFactory : IModelCacheKeyFactory 35 | { 36 | private static int Count; 37 | 38 | public object Create(DbContext context, bool designTime) 39 | => Interlocked.Increment(ref Count); 40 | } 41 | } 42 | 43 | internal class SingleEntityDbContext : DbContext where T : class 44 | { 45 | private readonly Action? _modelBuilderAction; 46 | 47 | public DbSet Entities { get; init; } 48 | 49 | public SingleEntityDbContext( 50 | DbContextOptions options, 51 | Action? modelBuilderAction = null) 52 | : base(options) 53 | { 54 | _modelBuilderAction = modelBuilderAction; 55 | } 56 | 57 | protected override void OnModelCreating(ModelBuilder modelBuilder) 58 | { 59 | base.OnModelCreating(modelBuilder); 60 | _modelBuilderAction?.Invoke(modelBuilder); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/TestUtilities/Utilities.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using System.Linq.Expressions; 17 | using System.Reflection; 18 | using Microsoft.EntityFrameworkCore; 19 | using Microsoft.EntityFrameworkCore.Infrastructure; 20 | using Microsoft.EntityFrameworkCore.Metadata; 21 | using MongoDB.EntityFrameworkCore.Extensions; 22 | 23 | namespace MongoDB.EntityFrameworkCore.UnitTests.TestUtilities; 24 | 25 | internal static class Utilities 26 | { 27 | public static string? GetCollectionName(this DbContext context) => 28 | context.Model.FindEntityType(typeof(TEntity))?.GetCollectionName(); 29 | 30 | public static IProperty? GetProperty(this DbContext context, 31 | Expression> propertyExpression) 32 | => context.Model.FindEntityType(typeof(TEntity))?.FindProperty(propertyExpression.GetMemberAccess()); 33 | 34 | public static PropertyInfo GetPropertyInfo(Expression> propertyExpression) 35 | { 36 | return propertyExpression.Body.NodeType switch 37 | { 38 | ExpressionType.MemberAccess => (PropertyInfo)((MemberExpression)propertyExpression.Body).Member, 39 | _ => throw new NotSupportedException($"NodeType '{propertyExpression.Body.NodeType}' not supported.") 40 | }; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/Usings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; 2 | global using MongoDB.EntityFrameworkCore.UnitTests.TestUtilities; 3 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/ValueGeneration/ObjectIdValueGeneratorTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using MongoDB.Bson; 17 | using MongoDB.EntityFrameworkCore.ValueGeneration; 18 | 19 | namespace MongoDB.EntityFrameworkCore.UnitTests.ValueGeneration; 20 | 21 | public class ObjectIdValueGeneratorTests 22 | { 23 | [Fact] 24 | public void Generates_non_temporary_ObjectIds() 25 | { 26 | var generator = new ObjectIdValueGenerator(); 27 | Assert.False(generator.GeneratesTemporaryValues); 28 | } 29 | 30 | [Fact] 31 | public void Next_generates_unique_ObjectId() 32 | { 33 | const int loops = 100; 34 | var generator = new ObjectIdValueGenerator(); 35 | var values = new HashSet(loops); 36 | 37 | for (var i = 0; i < loops; i++) 38 | values.Add(generator.Next(null!)); 39 | 40 | Assert.Equal(loops, values.Count); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/MongoDB.EntityFrameworkCore.UnitTests/ValueGeneration/StringObjectIdValueGeneratorTests.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2023-present MongoDB Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the 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 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | using MongoDB.EntityFrameworkCore.ValueGeneration; 17 | 18 | namespace MongoDB.EntityFrameworkCore.UnitTests.ValueGeneration; 19 | 20 | public class StringObjectIdValueGeneratorTests 21 | { 22 | [Fact] 23 | public void Generates_non_temporary_ObjectIdsAsStrings() 24 | { 25 | var generator = new StringObjectIdValueGenerator(); 26 | Assert.False(generator.GeneratesTemporaryValues); 27 | } 28 | 29 | [Fact] 30 | public void Next_generates_unique_ObjectIdAsStrings() 31 | { 32 | const int loops = 100; 33 | var generator = new StringObjectIdValueGenerator(); 34 | var values = new HashSet(loops); 35 | 36 | for (var i = 0; i < loops; i++) 37 | values.Add(generator.Next(null!)); 38 | 39 | Assert.Equal(loops, values.Count); 40 | } 41 | } 42 | --------------------------------------------------------------------------------