Entity Framework Ядро изменить отношение сущностей перед SaveChanges - PullRequest
0 голосов
/ 02 мая 2018

Есть ли способ обновить отношение сущностей перед общим вызовом SaveChanges?

public class Vehicle
{
    public int Id { get; set; }
    public int OwnerId { get; set; }
    [ForeignKey("OwnerId")]
    public Person Owner { get; set; }
}

Например, я хотел бы создать нового Person и назначить его для Vehicle до генерации Id (перед вызовом SaveChanges). Я знаю, что могу сделать это как:

entry.Property("OwnerId").CurrentValue = newId;

Но проблема в том, что я не знаю Id новой сущности до вызова SaveChanges.

То, чего я пытаюсь добиться, - это автоматически создать копию Владельца при ее изменении и назначить Владельца этой копии. Конечно, я должен сделать это как-то внутри переопределения SaveChanges.

Что-то вроде:

public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
{
    foreach (var entry in ChangeTracker.Entries())
    {
       foreach (var reference in entry.References)
       {
          if (reference.TargetEntry != null && reference.TargetEntry.State == EntryState.Modified)
          {
              // make a copy of target entry and update reference to it,
             // note: you can't really add new entries inside this loop as it will throw an exception, so all the adding has to be done outside
            // I would like to set this newEntity as the Owner
            var newEntity = (BaseEntity)entry.CurrentValues.ToObject();
            newEntity.Id = 0;
          }
       }
    }
    return await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}

Как я хочу, чтобы это работало:

//would insert new Person row and update OwnerId to point to this new row
vehicle.Owner.Name = "NewName";

1 Ответ

0 голосов
/ 02 мая 2018

Вы должны обновить ссылку, чтобы идентификатор обновлялся, когда у вас нет идентификатора:

public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
{
    foreach (var entry in ChangeTracker.Entries())
    {
       bool shouldUpdateReference = false;

       foreach (var reference in entry.References)
       {
           if (reference.TargetEntry != null && reference.TargetEntry.State == EntryState.Modified)
           {
               shouldUpdateReference = true;
           }
       }

        // I imagine this has to be done outside the foreach 
        // since you are modifying a reference and that should 
        // update the References collection
        if (shouldUpdateReference)
        {
            entity.Reference("Owner").CurrentValue = newOwner; 
        }
    }

    return await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...