Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve null handling #1614

Open
latonz opened this issue Nov 27, 2024 · 3 comments
Open

Improve null handling #1614

latonz opened this issue Nov 27, 2024 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@latonz
Copy link
Contributor

latonz commented Nov 27, 2024

Currently, Mapperly upgrades non-nullable reference types to annotated nullable reference types early in the mapping pipeline. Additionally, when nullables are involved, Mapperly incorporates null handling into the mapping process and continues the pipeline with non-nullable types. This approach centralizes null handling, making it simple and consistent.

However, this design has led to several bugs, indicating the need for a more robust solution. We need to define a clear concept to address these issues and improve the handling of nullable reference types without compromising simplicity or maintainability.

Related Bugs:

See also #1117 (comment).

@latonz latonz added the bug Something isn't working label Nov 27, 2024
@latonz latonz self-assigned this Dec 8, 2024
@TonEnfer
Copy link
Contributor

TonEnfer commented Dec 9, 2024

I think that when doing this task, you should also take into account similar conversions from #1117:

Source Is nullable Target Is nullable Expected result
class A {} true class B { static B Create(A source) } false target = global::B.Create(source ?? throw new ArgumentNullException(nameof(source)));
class A {} false class B { static B? Create(A source) } false target = global::B.Create(source) ?? throw new ArgumentNullException();
class A {} false struct B { static B? Create(A source) } false target = global::B.Create(source) ?? throw new ArgumentNullException();

or

target = global::B.Create(source).GetValueOrDefault();

Also pay attention to the results of these two tests:

public void MapNonNullableValueTypeToNullableValueType()
{
var source = TestSourceBuilder.Mapping("B", "A?", "struct A { public static A FromB(B source) => new(); }; struct B {}");
TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (global::A?)global::A.FromB(source);");
}
[Fact]
public void MapNonNullableValueTypeToNullableValueTypeWithNullableMethodParameter()
{
var source = TestSourceBuilder.Mapping("B", "A?", "struct A { public static A FromB(B? source) => new(); }; struct B {}");
TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return global::A.FromB(source);");
}

@CoreDX9
Copy link

CoreDX9 commented Dec 24, 2024

Can null value assignments be configured separately for each property?
Like this:

[AllowNullPropertyAssignment(false, Include = ["ArrayProp1", "ListProp2"])]
public static partial void UpdateEntity(this UpdateDto dto, MyEntity entity);

This way, null values can be used in the collection navigation properties to indicate that the collection navigation properties are not modified when update entity using EF Core.

@latonz
Copy link
Contributor Author

latonz commented Jan 6, 2025

This is not yet possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants