diff --git a/src/JsonApiDotNetCore.SourceGenerators/SourceCodeWriter.cs b/src/JsonApiDotNetCore.SourceGenerators/SourceCodeWriter.cs index 648906e901..0ce666e342 100644 --- a/src/JsonApiDotNetCore.SourceGenerators/SourceCodeWriter.cs +++ b/src/JsonApiDotNetCore.SourceGenerators/SourceCodeWriter.cs @@ -98,7 +98,7 @@ private void WriteNullableEnable() private void WriteNamespaceImports(INamedTypeSymbol loggerFactoryInterface, INamedTypeSymbol resourceType, string? controllerNamespace) { - _sourceBuilder.AppendLine($@"using {loggerFactoryInterface.ContainingNamespace};"); + _sourceBuilder.AppendLine($"using {loggerFactoryInterface.ContainingNamespace};"); _sourceBuilder.AppendLine("using JsonApiDotNetCore.Configuration;"); _sourceBuilder.AppendLine("using JsonApiDotNetCore.Controllers;"); @@ -123,7 +123,7 @@ private void WriteOpenClassDeclaration(string controllerName, JsonApiEndpointsCo string baseClassName = GetControllerBaseClassName(endpointsToGenerate); WriteIndent(); - _sourceBuilder.AppendLine($@"public sealed partial class {controllerName} : {baseClassName}<{resourceType.Name}, {idType}>"); + _sourceBuilder.AppendLine($"public sealed partial class {controllerName} : {baseClassName}<{resourceType.Name}, {idType}>"); WriteOpenCurly(); } diff --git a/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs b/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs index 66abfafbe0..6b36d9d84c 100644 --- a/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs +++ b/src/JsonApiDotNetCore/Repositories/EntityFrameworkCoreRepository.cs @@ -619,7 +619,18 @@ protected async Task UpdateRelationshipAsync(RelationshipAttribute relationship, private bool RequireLoadOfInverseRelationship(RelationshipAttribute relationship, [NotNullWhen(true)] object? trackedValueToAssign) { // See https://github.com/json-api-dotnet/JsonApiDotNetCore/issues/502. - return trackedValueToAssign != null && relationship is HasOneAttribute { IsOneToOne: true }; + if (trackedValueToAssign != null && relationship is HasOneAttribute { IsOneToOne: true }) + { + IEntityType? leftEntityType = _dbContext.Model.FindEntityType(relationship.LeftType.ClrType); + INavigation? navigation = leftEntityType?.FindNavigation(relationship.Property.Name); + + if (navigation != null && navigation.ForeignKey.DeclaringEntityType.ClrType == relationship.LeftType.ClrType) + { + return true; + } + } + + return false; } protected virtual async Task SaveChangesAsync(CancellationToken cancellationToken) diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/MusicTrack.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/MusicTrack.cs index 52ed0ae98b..0abf7385ee 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/MusicTrack.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/MusicTrack.cs @@ -9,7 +9,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations; [Resource(ControllerNamespace = "JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations")] public sealed class MusicTrack : Identifiable { - [RegularExpression(@"(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$")] + [RegularExpression("(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$")] public override Guid Id { get; set; } [Attr] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiControllerTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiControllerTests.cs index 88e9ecfd82..3c4a6a6bae 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiControllerTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/NonJsonApiControllerTests.cs @@ -41,14 +41,13 @@ public async Task Get_skips_middleware_and_formatters() public async Task Post_skips_middleware_and_formatters() { // Arrange - using var request = new HttpRequestMessage(HttpMethod.Post, "/NonJsonApi") + using var request = new HttpRequestMessage(HttpMethod.Post, "/NonJsonApi"); + + request.Content = new StringContent("Jack") { - Content = new StringContent("Jack") + Headers = { - Headers = - { - ContentType = new MediaTypeHeaderValue("text/plain") - } + ContentType = new MediaTypeHeaderValue("text/plain") } }; @@ -90,14 +89,13 @@ public async Task Post_skips_error_handler() public async Task Put_skips_middleware_and_formatters() { // Arrange - using var request = new HttpRequestMessage(HttpMethod.Put, "/NonJsonApi") + using var request = new HttpRequestMessage(HttpMethod.Put, "/NonJsonApi"); + + request.Content = new StringContent("\"Jane\"") { - Content = new StringContent("\"Jane\"") + Headers = { - Headers = - { - ContentType = new MediaTypeHeaderValue("application/json") - } + ContentType = new MediaTypeHeaderValue("application/json") } }; diff --git a/test/SourceGeneratorTests/ControllerGenerationTests.cs b/test/SourceGeneratorTests/ControllerGenerationTests.cs index 629c5d49b8..44c63ffe54 100644 --- a/test/SourceGeneratorTests/ControllerGenerationTests.cs +++ b/test/SourceGeneratorTests/ControllerGenerationTests.cs @@ -538,7 +538,7 @@ public sealed class Item : Identifiable GeneratorDriverRunResult runResult = driver.GetRunResult(); runResult.Should().NotHaveDiagnostics(); - runResult.Should().HaveProducedSourceCodeContaining(@"#nullable enable"); + runResult.Should().HaveProducedSourceCodeContaining("#nullable enable"); } [Fact]