Entity Framework — чтение обновлений перед сохранением

#c# #entity-framework

#c# #entity-framework

Вопрос:

В EF 6, когда я делаю обновление записи в объекте, перед сохранением изменений, вызывая _context.SaveChanges(), я должен иметь возможность получить доступ к этой обновленной записи вместе с другими записями в другой функции, чтобы иметь возможность подтвердить изменение.

 public bool UpdateToFlase(int id, int accountNumber)
{
    var charge = _context.CHARGES.FirstOrDefault(x=>x.Id == id).Active = False;
    if(!IsValid(accountNumber))
        return false;
    _context.SaveChanges();
    return true;
}

public bool IsValid(int accountNumber)
{
    return _context.CHARGES.Where(x=>x.AccountNumber == accountNumber amp;amp; x.Active).Sum(x=>x.Charge) >=0;
    
    //I noticed that the above update that i made is only in _context.CHARGES.Local and by accessing _context.CHARGES, 
    //i'm unable to access the updates. I was hoping to find a way to access records along with the updated one.
}


Given:
    Id  AccountNumber   Charge  Active
    1   10001           100     True
    2   10001           -100    True
    
When
    UpdateToFalse(1, 10001)
Then
    Actual:
        return TRUE
    Expected:
        return FALSE

Expectation 
    In IsValid function, (-100 >= 0) should return false
  

Ответ №1:

Я полагаю, что вы пытаетесь получить доступ к объекту, который загружен в вашу коллекцию dbset в вашем контексте, который не будет «обновляться» до тех пор, пока вы не вызовете

  SaveChanges()
  

Я полагаю, это связано с тем, что EF отслеживает каждую сущность с момента, когда вы впервые загрузили их в свою коллекцию. Я думаю, что он не будет «обновлен», пока вы не «обновите» его при вызове SaveChanges()

Может быть, вы могли бы попробовать передать измененный объект в функцию isValid и, возможно, изменить функцию isValid, чтобы она могла проверять значение, которое вы пытаетесь сохранить?

Возможно, эта статья поможет вам предотвратить сохранение нежелательной сущности в базе данных:

https://dotnettutorials.net/lesson/entity-state-in-entity-framework/

Ответ №2:

Я взял измененные и удаленные объекты, подобные этому

             var modifiedEntities = _context.ChangeTracker.Entries()
                .Where(p => p.State == EntityState.Modified || p.State == EntityState.Deleted)
                .ToList();

            foreach (var change in modifiedEntities)
            {
                Validate(change);
            }
  

Ответ №3:

Мой подход, который сработал:

 public bool UpdateToFlase(int id, int accountNumber)
{
    var charge = _context.CHARGES.FirstOrDefault(x=>x.Id == id).Active = False;
    if(!IsValid(_context.CHARGES.Where(x=>x.AccountNumber == accountNumber).ToList()))
        return false;
    _context.SaveChanges();
    return true;
}

public bool IsValid(List<CHARGES> charges)
{
    return charges.Where(x=>/*What ever the criteria is */ x.Active).Sum(x=>x.Charge) >=0;
    
    //This way, we are referring to same scope as the above function 
}
  

Ответ №4:

Это не учитывало бы одновременные запросы, но, предполагая, что это не проблема, вы могли бы сделать следующее:

 public bool IsValid(int id, int accountNumber)
{
    return _context.CHARGES.Where(x=>x.AccountNumber == accountNumber amp;amp; x.Active amp;amp; x.Id != id).Sum(x=>x.Charge) >=0;
}
  

То, что вы пытаетесь сделать, это получить общую сумму всех активных платежей, кроме того, который вы хотите сделать неактивным, поэтому в приведенном выше примере этот платеж специально исключен.

То, как вы пытаетесь это сделать, не сработает, поскольку база данных не обновляется до тех пор, пока вы не вызовете SaveChanges() .

Комментарии:

1. Я добавил пример кода в свой вопрос. В режиме реального времени я обновляю множество коллекций и пытаюсь проверить все эти коллекции в IsValid функции.