Wykonywanie własnego kodu, podczas wywołania metody SaveChanges
Wystarczy nadpisać metodę SaveChanges z obiektu kontekstu. Stan obiektów dostępny jest w ObjectStateManager.
public override int SaveChanges(SaveOptions options) { Console.WriteLine("Saving Changes"); var applicants = this.ObjectStateManager .GetObjectStateEntries(EntityState.Deleted) .Select(e => e.Entity) .OfType<Applicant>().ToList(); int changes = base.SaveChanges(options); Console.WriteLine("\n{0} applicants deleted", applicants.Count().ToString()); foreach (var applicant in applicants) { File.Delete(applicant.ResumePath); Console.WriteLine("\n{0}File deleted at {1}", applicant.Name, applicant.ResumePath); } return changes; }
Reguły walidacyjne dla propercji
Aby dodać prostą regułę walidacyjną należy na obiekcie encji nadpisać metody zgodne z nazwą property. Metody te generowane są przez EF. Na przykład dla property UserName mamy możliwe OnUserNameChanging oraz OnUserNameChanged. W tych metodach mamy dostęp do encji, więc możemy modyfikować jej pola. Metody takie wołane są nie tylko przy zmianie wartości property ale także przy materializowaniu encji podczas jej pobierania z bazy danych.
public partial class User { partial void OnUserNameChanging(string value) { if (value.Length > 5) Console.WriteLine("{0}'s UserName changing to {1}, OK!", this.FullName, value); else Console.WriteLine("{0}'s UserName changing to {1}, TooShort!", this.FullName, value); } partial void OnUserNameChanged() { this.IsActive = this.UserName.Length > 5; } }
Logowanie połączeń do bazy danych
Aby logować połączenia możemy zasubskrybować się na zdarzenie StateChange z property Connection dostępnej w obiekcie kontekstu.
this.Connection.StateChange += (s, e) => { var conn = ((EntityConnection) s).StoreConnection; Console.WriteLine("{0}: Database: {1}, State: {2} was {3}", DateTime.Now.ToShortTimeString(), conn.Database, e.CurrentState, e.OriginalState); };
Walidacja przy SaveChanges
Czasami do walidacji potrzebujemy dwie wartości encji: nową i poprzednią (np. procentowy przyrost płac). Odpowiednim miejscem, w którym mamy dostęp do obu wartości jest zdarzenie SavingChanges.
public partial class EntityFrameworkRecipesEntities3 { partial void OnContextCreated() { this.SavingChanges += new EventHandler(EntityFrameworkRecipesEntities3_SavingChanges); } void EntityFrameworkRecipesEntities3_SavingChanges(object sender, EventArgs e) { var entries = this.ObjectStateManager .GetObjectStateEntries(EntityState.Modified) .Where(entry => entry.Entity is Employee); foreach(var entry in entries) { var salaryProp = entry.GetModifiedProperties() .FirstOrDefault(p => p == "Salary"); if(salaryProp != null) { var originalSalary = Convert.ToDecimal( entry.OriginalValues[salaryProp]); var currentSalary = Convert.ToDecimal( entry.CurrentValues[salaryProp]); if(originalSalary != currentSalary) { if(currentSalary > 1.1M*originalSalary) { throw new ApplicationException("Can't increase salary more than 10%"); } } } } } }
Brak komentarzy:
Prześlij komentarz