mercredi 1 septembre 2021

Updating navigational properties sets them to null in EF Core

I have a situation when I'm attempting to update navigational properties in Entity Framework Core and I'm getting some unusual behaviour where it sets the value to null which then removes the record from the database.

Simplified example:

public class Hla : BaseEntity
{
    public string AField1 { get; set; }
    public virtual Patient Patient { get; set; }
    public int PatientId { get; set; }
}

public class Patient : BaseEntity
{
    public string Test { get; set; }
    public virtual Hla Hla { get; set; }
}

public class PatientRepository : Repository, IPatientRepository
{
    private readonly SearchAndMatchContext _context;

    public PatientRepository(SearchAndMatchContext context) : base(context)
    {
        _context = context;
    }

    public async Task<Patient> RetrieveEntity(int id)
    {
        return await _context.Patients
            .Include(t=>t.Hla)
            .FirstOrDefaultAsync(t => t.Id == id);
    }

    public  void UpdateEntity(Patient entity)
    {
        _context.Patients.Update(entity);
    }
}

The code that's causing the issue:

private static Hla Map(Hla original, Hla update)
{
    var  fieldsToSkip = new string[]{"Id"};
    
    PropertyInfo[] fields = update.GetType().GetProperties();

    foreach (var field in fields)
    {
        if (fieldsToSkip.Contains(field.Name))
        {
            continue;
        }

        var newValue = field.GetValue(update);
        field.SetValue(original, newValue);
    }

    return original;
}

var patient = await _patientRepository.RetrieveEntity(1);

Map(patient.Hla, new Hla
    {
        AField1 = "dfgdfg",
        PatientId = patient.Id
    });

patientRepository.UpdateEntity(patient);
await _patientRepository.UnitOfWork.SaveChangesAsync();

As soon as the SaveChangesAsync is called, the Hla is being set to null - output from the immediate window:

enter image description here

Whereas, if I have a simple "direct" mapper, it seems to work perfectly.

More simple mapper:

private static void Map(Hla current, Hla update)
{
    current.AField1 = update.AField1;
}

Then I get the immediate window output as:

enter image description here

I'm a little bit confused about why this happens, it seems to make no sense to me.

This also happens if I use an automapper etc.

What am I missing?





Aucun commentaire:

Enregistrer un commentaire