c# tutorial Log di controllo di Entity Framework 7




use entity framework (2)

Fondamentalmente hai due modi per ottenere questo:

Utilizzo dell'API ChangeTracker (EF 6+):

Questo è il modo in cui lo facciamo attualmente in EF 6 ed è ancora valido e funzionante per EF 7:

Innanzitutto devi assicurarti che le tue entità stiano implementando un'interfaccia comune per i campi di controllo:

public interface IAuditableEntity 
{
    int? CreatedById { get; set; }

    DateTime Created { get; set; }

    int? ModifiedById { get; set; }

    DateTime Modified { get; set; }
}


Quindi puoi sovrascrivere SaveChanges e aggiornare ogni campo comune con i valori di controllo:

public override int SaveChanges()
{
    int? userId = null;
    if (System.Web.HttpContext.Current != null)
        userId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault();

    var modifiedEntries = ChangeTracker.Entries<IAuditableEntity>()
            .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified);

    foreach (EntityEntry<IAuditableEntity> entry in modifiedEntries)
    {
        entry.Entity.ModifiedById = UserId;
        entry.Entity.Modified = DateTime.Now;

        if (entry.State == EntityState.Added)
        {
            entry.Entity.CreatedById = UserId;
            entry.Entity.Created = DateTime.Now;
        }
    }

    return base.SaveChanges();
}


Usando EF 7 nuova funzione "Proprietà ombra":

Le proprietà shadow sono proprietà che non esistono nella classe entità. Il valore e lo stato di queste proprietà sono mantenuti puramente nel Change Tracker.

In altre parole, le colonne di controllo non saranno esposte sulle tue entità che sembra essere un'opzione migliore rispetto a quella sopra in cui devi includerle nelle tue entità.

Per implementare le proprietà shadow, devi prima configurarle sulle tue entità. Diciamo per esempio che hai un oggetto User che deve avere alcune colonne di controllo:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>().Property<int>("CreatedById");

    modelBuilder.Entity<User>().Property<DateTime>("Created");

    modelBuilder.Entity<User>().Property<int>("ModifiedById");

    modelBuilder.Entity<User>().Property<DateTime>("Modified");
}


Una volta configurati, ora puoi accedervi con SaveChanges () e aggiornare i loro valori di conseguenza:

public override int SaveChanges()
{
    int? userId = null;
    if (System.Web.HttpContext.Current != null)
        userId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault();

    var modifiedBidEntries = ChangeTracker.Entries<User>()
        .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified);

    foreach (EntityEntry<User> entry in modifiedBidEntries)
    {
        entry.Property("Modified").CurrentValue = DateTime.UtcNow;
        entry.Property("ModifiedById").CurrentValue = userId;

        if (entry.State == EntityState.Added)
        {
            entry.Property("Created").CurrentValue = DateTime.UtcNow;
            entry.Property("CreatedById").CurrentValue = userId;
        }
    }

    return base.SaveChanges();
}


Pensieri finali:

Per implementare qualcosa come le colonne di controllo, prenderò l'approccio di Shadow Properties poiché questi sono problemi trasversali e non appartengono necessariamente ai miei oggetti di dominio, quindi farli implementare in questo modo manterrà gli oggetti del mio dominio belli e puliti.

Sto trasferendo un vecchio progetto su ASP.NET 5 e Entity Framework 7. Ho usato il primo approccio del database (scaffold DNX) per creare il modello.

Il vecchio progetto è basato su Entity Framework 4 e il controllo di verifica è implementato sovrascrivendo il metodo SaveChanges di DbContext :

public override int SaveChanges(System.Data.Objects.SaveOptions options)
{
    int? UserId = null;
    if (System.Web.HttpContext.Current != null) 
        UserId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault();

    foreach (ObjectStateEntry entry in ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
    {
        Type EntityType = entry.Entity.GetType();

        PropertyInfo pCreated = EntityType.GetProperty("Created");
        PropertyInfo pCreatedById = EntityType.GetProperty("CreatedById");
        PropertyInfo pModified = EntityType.GetProperty("Modified");
        PropertyInfo pModifiedById = EntityType.GetProperty("ModifiedById");

        if (entry.State == EntityState.Added)
        {
            if (pCreated != null)
                pCreated.SetValue(entry.Entity, DateTime.Now, new object[0]);
            if (pCreatedById != null && UserId != null)
                pCreatedById.SetValue(entry.Entity, UserId, new object[0]);
        }
        if (pModified != null)
            pModified.SetValue(entry.Entity, DateTime.Now, new object[0]);
        if (pModifiedById != null && UserId != null)
            pModifiedById.SetValue(entry.Entity, UserId, new object[0]);
        }
    }

    return base.SaveChanges(options);
}

La mia domanda è, come posso implementarlo in Entity Framework 7? Devo prendere il primo approccio del codice?


Ho lavorato su una libreria che potrebbe aiutare.

Dai un'occhiata alla libreria Audit.EntityFramework , intercetta SaveChanges() ed è compatibile con le versioni di EF Core.





entity-framework-core