vendredi 4 septembre 2020

Updating one-to-one parent/child with a generic method

I came across this question - Update parent and child collections on generic repository with EF Core, and liked the implementation of generic update for one-to-many parent/children by Ivan Stoev in the accepted answer.

I tried to mimic it to implement a one-to-one version for myself which was supposed to be the easier one. Following is the result of my struggle -

public async Task<int> UpdateAsync<T>(T entity, params Expression<Func<T, object>>[] navigations) where T : EntityBase
{
    var dbEntity = await _DbCtx.FindAsync<T>(entity.Id);

    var entry = _DbCtx.Entry(dbEntity);
    entry.CurrentValues.SetValues(entry);

    foreach (var nav in navigations)
    {
        string propertyName = nav.GetPropertyAccess().Name;        
        
        // Problem #01 //
        // if possible, I'd like to avoid this reflection in favor of EF Core MetaData?
        var child = (EntityBase)entity.GetType().GetProperty(propertyName).GetValue(entity);
        if (child == null)
            continue;            // if the client-sent model doesn't have child, skip

        var referenceEntry = entry.Reference(propertyName);
        await referenceEntry.LoadAsync();

        var dbChild = (EntityBase)referenceEntry.CurrentValue;
        if (dbChild == null)
        {
            // Problem #02 //
            // if the existing entity doesn't have child, the client-sent child will be assigned.
            // but I could not figure out how to do this
        }
        else
        {
            _DbCtx.Entry(dbChild).CurrentValues.SetValues(child);
        }
    }

    return await _DbCtx.SaveChangesAsync();
}

I have marked the problems as Problem #01 and Problem #02 in code comments above. Any suggestion, solution will be appreciated. Thanks.





Aucun commentaire:

Enregistrer un commentaire