How to clone an entity in Entity Framework Core?

Copy the values from the old period to the new period, then set properties with unique values (in this case, the primary key), and lastly add the entity to the DbContext.

var period2 = _tariffRepository.GetPeriodFull(period.GUID);
var period3 = new TariffPeriod();
_appDbContext.Entry(period3).CurrentValues.SetValues(period2);
period3.Id = 0;
_appDbContext.TariffPeriods.Add(period3);

Solution 1

This is my solution based on @grek40's solution with casting added to avoid string literals and allow for future refactoring.

_appDbContext helper method:

    public TEntity DetachedClone<TEntity>(TEntity entity) where TEntity : class
            => Entry(entity).CurrentValues.Clone().ToObject() as TEntity;

For your answer:

    var period2 = _tariffRepository.GetPeriodFull(period.GUID);
    var period3 = _appDbContext.DetachedClone(period2);
    _appDbContext.TariffPeriods.Add(period3);

Solution 2

You can use a simple JSON deep clone function as well. Works like charm. I prefer this method because the first solution involves attaching the entry first using .Entry() and that could be not desirable

    public static T Clone<T>(T source)
    {
        var serialized = JsonConvert.SerializeObject(source);
        return JsonConvert.DeserializeObject<T>(serialized);
    }

(ノ◕ヮ◕)ノ✲゚。⋆


You can try getting a clone of the period2 data and modify the Id before assigning to period3

var values = db.Entry(period2).CurrentValues.Clone();
values["Id"] = 0;
db.Entry(period3).CurrentValues.SetValues(values);