Próbuję zaimplementować auditlog używając EF 4.1, poprzez nadpisanie SaveChanges() metody, jak to omówiono w następujących miejscach:Entity Framework DbContext SaveChanges() OriginalValue Nieprawidłowa
- http://jmdority.wordpress.com/2011/07/20/using-entity-framework-4-1-dbcontext-change-tracking-for-audit-logging/
- Entity Framework 4.1 DbContext Override SaveChanges to Audit Property Change
Mam problemy z wpisami "zmodyfikowanymi". Ilekroć próbuję uzyskać w danej właściwości OriginalValue, zawsze ma ona tę samą wartość, co w polu CurrentValue.
raz pierwszy użyć tego kodu, i to skutecznie identyfikuje wpisy, które są modyfikowane:
public int SaveChanges(string userID)
{
// Have tried both with and without the following line, and received same results:
// ChangeTracker.DetectChanges();
foreach (
var ent in this.ChangeTracker
.Entries()
.Where(p => p.State == System.Data.EntityState.Added
p.State == System.Data.EntityState.Deleted
p.State == System.Data.EntityState.Modified))
{
// For each change record, get the audit record entries and add them
foreach (AuditLog log in GetAuditRecordsForChange(ent, userID))
{
this.AuditLog.Add(log);
}
}
return base.SaveChanges();
}
Problem polega na tym (kod skróconej):
private List<AuditLog> GetAuditRecordsForChange(DbEntityEntry dbEntry, string userID)
{
if (dbEntry.State == System.Data.EntityState.Modified)
{
foreach (string propertyName in dbEntry.OriginalValues.PropertyNames)
{
if (!object.Equals(dbEntry.OriginalValues.GetValue<object>(propertyName),
dbEntry.CurrentValues.GetValue<object>(propertyName)))
{
// It never makes it into this if block, even when
// the property has been updated.
}
// If I updated the property "Name" which was originally "OldName" to the value "NewName" and then break here and inspect the values by calling:
// ?dbEntry.OriginalValues.GetValue<object>("Name").ToString()
// the result will be "NewName" and not "OldName" as expected
}
}
}
Najdziwniejsze jest to, że zadzwoń pod dbEntry.Property(propertyName).IsModified();
będzie zwraca true w tym przypadku. Po prostu wartość OriginalValue nie ma oczekiwanej wartości w środku. Czy ktoś byłby chętny do wskazania mi właściwego kierunku? Nie wydaje mi się, żeby to działało poprawnie.
W jaki sposób wyszukujesz swoje jednostki, a następnie zmieniasz wartości właściwości? Jeśli zasadniczo dołączasz obiekt, a następnie ustawiasz stan na Zmodyfikowany, wówczas pierwotne wartości zostaną utracone. Aby zachować pierwotne wartości, musisz albo EF śledzić encję od zapytania do zapisu, albo musisz śledzić oryginalne wartości we własnym kodzie. –
Przepraszamy - próbowałem opublikować kod w komentarzach, ale nie działał dobrze.Używam działania [HttpPost] kontrolera MVC. To wywołuje metodę "SaveProduct" w moim repozytorium produktu. W repozytorium wygląda na to, że rzeczywiście nazywam "context.Entry (product) .State = EntityState.Modified', a następnie I SaveChanges na kontekście. Czy byłbyś w stanie wskazać mi jakieś zasoby, które demonstrują dwie wspomniane techniki? A przynajmniej daj mi kilka wskazówek? –
Ithink_ w MVC zalecany sposób to zrobić z ukrytych pól. Zasadniczo zapisałeś pierwotne wartości, które cię interesują, w ukrytych polach, a następnie przeczytałeś je później w swoim POST. Nie znam najlepszych praktyk w tym zakresie lub jeśli istnieje abstrakcja MVC, aby pomóc. –