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

Configuring null foreign keys not to be mapped to corresponding object property #121

Closed
johnhamm opened this issue Mar 12, 2019 · 4 comments
Assignees
Labels

Comments

@johnhamm
Copy link

Given I have four classes defined as:

    public class Person {
        public int Id { get; set; }
        public string Name { get; set; }
        public int? PetId { get; set; }
        public Pet Pet { get; set; }
    }

    public class PersonDto {
        public int Id { get; set; }
        public string Name { get; set; }
        public int? PetId { get; set; }
    }

    public class Pet {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class PetDto {
        public int Id { get; set; }
        public string Name { get; set; }
    }

And I map a PersonDto to a Person:

    var personDto = new PersonDto { Id = 1, Name = "John" };
    var person = personDto.Map().ToANew<Person>();

The resulting object is:

{AgileMapperLab.Person}
  Id: 1
  Name: "John"
  PetId: null
  Pet: { }
    {AgileMapperLab.Pet}
      Id: 0
      Name: null

Even though PetId is null in the original PersonDto, AgileMapper creates a new empty Pet anyway. The issue is that Entity Framework Core sees these as newly added objects and will add them to a database, even though pet is optional for a person.

Is there a way to turn this behavior off in AgileMapper so that if a "foreign key" in an object is null (or 0), do not instantiate a new object for the matching object property?

@johnhamm johnhamm changed the title Configuring null keys to not be mapped Configuring null foreign keys not to be mapped to corresponding object property Mar 12, 2019
@johnhamm johnhamm reopened this Mar 12, 2019
@johnhamm
Copy link
Author

I was able to bypass the new object creation by using IgnoreEntityKeys:

personDto.Map().ToANew<Person>(cfg => cfg.IgnoreEntityKeys())

Unfortunately, this also ignores the primary key Id field from the original DTO and Entity Framework Core then thinks it is a new object.

@SteveWilkes
Copy link
Member

Hi John!

Hmm - that's certainly not the intended behaviour - I'll take a look and sort it out.

In the meantime, you can work around it using:

Mapper.WhenMapping
    .ToANew<Pet>()
    .If((o, p) => string.IsNullOrEmpty(p.Name))
    .MapToNull();

I've put together a fiddle showing this at work :)

Cheers,

Steve

@SteveWilkes SteveWilkes self-assigned this Mar 13, 2019
SteveWilkes added a commit that referenced this issue Mar 22, 2019
…ted member is an identifier, and it isn't given a non-default value. Fixes #121.
@SteveWilkes
Copy link
Member

SteveWilkes commented Mar 22, 2019

This is fixed in the latest code - if the only member of a complex type member mapped during a mapping is an identifier, and it isn't given a non-default value, the complex type member isn't populated. If non-identifier members are included in the mapping - like if Person in this example had a PetName property - no check is performed. .MapToNull() can be used to configure null mappings in cases like that.

Release to follow. Thanks for the feedback! :)

@SteveWilkes
Copy link
Member

This is fixed as of v1.3-preview2.

@SteveWilkes SteveWilkes added the in-preview A feature or bug fix exists in a preview release, and a full release will follow label Mar 29, 2019
@SteveWilkes SteveWilkes removed the in-preview A feature or bug fix exists in a preview release, and a full release will follow label Apr 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants