2014-01-06 7 views
0

Я создаю приложение с MVC4 и инфраструктурой сущности 5. Как я могу это реализовать? Я огляделся и обнаружил, что мне нужно переопределить SaveChanges.entity framework 5 изменить журнал как реализовать?

У кого-нибудь есть образец кода? Я использую первый подход к коду.

В качестве примера, как я спасаю данные следующим образом,

public class AuditZoneRepository : IAuditZoneRepository 
    { 
     private AISDbContext context = new AISDbContext(); 



     public int Save(AuditZone model, ModelStateDictionary modelState) 
     { 
      if (model.Id == 0) 
      { 
       context.AuditZones.Add(model); 
      } 
      else 
      { 
       var recordToUpdate = context.AuditZones.FirstOrDefault(x => x.Id == model.Id); 
       if (recordToUpdate != null) 
       { 
        recordToUpdate.Description = model.Description; 
        recordToUpdate.Valid = model.Valid; 
        recordToUpdate.ModifiedDate = DateTime.Now; 
       } 
      } 

      try 
      { 
       context.SaveChanges(); 
       return 1; 
      } 
      catch (Exception ex) 
      { 
       modelState.AddModelError("", "Database error has occured. Please try again later"); 
       return -1; 
      } 
     } 
    } 

ответ

0

Там нет необходимости переопределять SaveChanges.

Вы можете

Trigger Context.ChangeTracker.DetectChanges(); // может потребоваться в зависимости от вашего прокси подход

Затем проанализировать контекст перед сохранением. , вы можете ... добавить журнал изменений в CURRENT Unit of work. Таким образом, журнал сохраняется в одной транзакции COMMIT. Или обрабатывайте его так, как вы считаете нужным. Но сохранение журнала изменений в одно и то же время. гарантирует, что это ОДНА Сделка.

Анализ образца контекста: У меня есть простой инструмент для создания контекстного содержимого Dump для отладки вывода, поэтому, когда в отладчике я могу использовать немедленное окно для проверки содержимого. например Вы можете использовать это как стартер, чтобы подготовить свой журнал CHANGE. Попробуйте в ближайшем окне отладчика. У меня FULL дамп в моем классе Context.

Образец Немедленный вызов окна. UoW.Context.FullDump();

общественный недействительный FullDump() {

 Debug.WriteLine("=====Begin of Context Dump======="); 
     var dbsetList = this.ChangeTracker.Entries(); 
     foreach (var dbEntityEntry in dbsetList) 
     { 

      Debug.WriteLine(dbEntityEntry.Entity.GetType().Name + " => " + dbEntityEntry.State); 
      switch (dbEntityEntry.State) 
      { 
       case EntityState.Detached: 
       case EntityState.Unchanged: 
       case EntityState.Added: 
       case EntityState.Modified: 
        WriteCurrentValues(dbEntityEntry); 
        break; 
       case EntityState.Deleted: 
        WriteOriginalValues(dbEntityEntry); 
        break; 
       default: 
        throw new ArgumentOutOfRangeException(); 
      } 
      Debug.WriteLine("==========End of Entity======"); 
     } 
     Debug.WriteLine("==========End of Context======"); 
    } 

    private static void WriteCurrentValues(DbEntityEntry dbEntityEntry) 
    { 
     foreach (var cv in dbEntityEntry.CurrentValues.PropertyNames) 
     { 
      Debug.WriteLine(cv + "=" + dbEntityEntry.CurrentValues[cv]); 
     } 
    } 
    private static void WriteOriginalValues(DbEntityEntry dbEntityEntry) 
    { 
     foreach (var cv in dbEntityEntry.OriginalValues.PropertyNames) 
     { 
      Debug.WriteLine(cv + "=" + dbEntityEntry.OriginalValues[cv]); 
     } 
    } 
} 

EDIT: получить изменения

Я использую эту процедуру, чтобы получить chnages ...

public class ObjectPair { 
    public string Key { get; set; } 
    public object Original { get; set; } 
    public object Current { get; set; } 
} 

public virtual IList<ObjectPair> GetChanges(object poco) { 
     var changes = new List<ObjectPair>(); 
     var thePoco = (TPoco) poco; 


     foreach (var propName in Entry(thePoco).CurrentValues.PropertyNames) { 
      var curr = Entry(thePoco).CurrentValues[propName]; 
      var orig = Entry(thePoco).OriginalValues[propName]; 
      if (curr != null && orig != null) { 
       if (curr.Equals(orig)) { 
        continue; 
       } 
      } 
      if (curr == null && orig == null) { 
       continue; 
      } 
      var aChangePair = new ObjectPair {Key = propName, Current = curr, Original = orig}; 
      changes.Add(aChangePair); 
     } 
     return changes; 
    } 

редактировать- Если вы должны использовать отслеживание внутренних объектов.

var context = ???// YOUR DBCONTEXT class 
    // get objectcontext from dbcontext... 
    var objectContext = ((IObjectContextAdapter) context).ObjectContext; 
     // for each tracked entry 
     foreach (var dbEntityEntry in context.ChangeTracker.Entries()) { 
      //get the state entry from the statemanager per changed object 
      var stateEntry = objectContext.ObjectStateManager.GetObjectStateEntry(dbEntityEntry.Entity); 
      var modProps = stateEntry.GetModifiedProperties(); 
      Debug.WriteLine(modProps.ToString()); 
     } 

Я декомпилировал EF6. В результате модификации действительно используется частный бит-массив для отслеживания полей, которые изменили .

// EF decompiled source..... _modifiedFields is a bitarray 
public override IEnumerable<string> GetModifiedProperties() 
{ 
    this.ValidateState(); 
    if (EntityState.Modified == this.State && this._modifiedFields != null) 
    { 
    for (int i = 0; i < this._modifiedFields.Length; ++i) 
    { 
     if (this._modifiedFields[i]) 
     yield return this.GetCLayerName(i, this._cacheTypeMetadata); 
    } 
    } 
} 
+0

Phil - это отличный образец. Спасибо. Я обновил свой код выше, я не использую единицу работы. Итак, вы говорите, прежде чем я сэкономлю, я должен отслеживать изменения, чтобы сравнить два набора значений? также, если у меня разные репозитории, мне придется дублировать код? – user2206329

+0

имеет много репозиториев в порядке. Код предназначен для контекста, поэтому его можно учесть. т.е. просто пройти в контексте. Рассмотрим подход «Единица работы», в котором вы контролируете сохранение, - это то, где можно управлять журналом изменений. причина, по которой существует шаблон UOW, заключается в том, чтобы избежать 500 методов сохранения в репозиториях ;-) –

+0

phil - есть ли простой способ просто идентифицировать только измененные значения? В записи я могу изменить только одно поле. так же функция текущего значения отображает только элемент, который был изменен, или он отображает все поля для этой записи? – user2206329

Смежные вопросы