Base de données première approche avec journalisation CRUD automatique


Question

J'ai configuré EF + Audit comme suit:

public partial class FocusConnection : DbContext
{
    static FocusConnection()
    {
        AuditManager.DefaultConfiguration.AutoSavePreAction = (context, audit) =>
           // ADD "Where(x => x.AuditEntryID == 0)" to allow multiple SaveChanges with same Audit
           (context as FocusConnection).AuditEntries.AddRange(audit.Entries);
    }

    public override int SaveChanges()
    {
        var audit = new Audit();
        audit.PreSaveChanges(this);
        var rowAffecteds = base.SaveChanges();
        audit.PostSaveChanges();

        if (audit.Configuration.AutoSavePreAction != null)
        {
            audit.Configuration.AutoSavePreAction(this, audit);
            base.SaveChanges();
        }

        return rowAffecteds;
    }

    public override Task<int> SaveChangesAsync()
    {
        return SaveChangesAsync(CancellationToken.None);
    }

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
    {
        var audit = new Audit();
        audit.PreSaveChanges(this);
        var rowAffecteds = await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
        audit.PostSaveChanges();

        if (audit.Configuration.AutoSavePreAction != null)
        {
            audit.Configuration.AutoSavePreAction(this, audit);
            await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
        }

        return rowAffecteds;
    }

}

J'ai utilisé une classe partielle pour rester en dehors du contexte original basé sur un modèle de texte généré par EF6. J'ai utilisé le script SQL suivant pour générer les deux tables telles quelles:

public partial class FocusConnection : DbContext
{
    static FocusConnection()
    {
        AuditManager.DefaultConfiguration.AutoSavePreAction = (context, audit) =>
           // ADD "Where(x => x.AuditEntryID == 0)" to allow multiple SaveChanges with same Audit
           (context as FocusConnection).AuditEntries.AddRange(audit.Entries);
    }

    public override int SaveChanges()
    {
        var audit = new Audit();
        audit.PreSaveChanges(this);
        var rowAffecteds = base.SaveChanges();
        audit.PostSaveChanges();

        if (audit.Configuration.AutoSavePreAction != null)
        {
            audit.Configuration.AutoSavePreAction(this, audit);
            base.SaveChanges();
        }

        return rowAffecteds;
    }

    public override Task<int> SaveChangesAsync()
    {
        return SaveChangesAsync(CancellationToken.None);
    }

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
    {
        var audit = new Audit();
        audit.PreSaveChanges(this);
        var rowAffecteds = await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
        audit.PostSaveChanges();

        if (audit.Configuration.AutoSavePreAction != null)
        {
            audit.Configuration.AutoSavePreAction(this, audit);
            await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
        }

        return rowAffecteds;
    }

}

Je reçois une erreur dans le constructeur statique:

public partial class FocusConnection : DbContext
{
    static FocusConnection()
    {
        AuditManager.DefaultConfiguration.AutoSavePreAction = (context, audit) =>
           // ADD "Where(x => x.AuditEntryID == 0)" to allow multiple SaveChanges with same Audit
           (context as FocusConnection).AuditEntries.AddRange(audit.Entries);
    }

    public override int SaveChanges()
    {
        var audit = new Audit();
        audit.PreSaveChanges(this);
        var rowAffecteds = base.SaveChanges();
        audit.PostSaveChanges();

        if (audit.Configuration.AutoSavePreAction != null)
        {
            audit.Configuration.AutoSavePreAction(this, audit);
            base.SaveChanges();
        }

        return rowAffecteds;
    }

    public override Task<int> SaveChangesAsync()
    {
        return SaveChangesAsync(CancellationToken.None);
    }

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
    {
        var audit = new Audit();
        audit.PreSaveChanges(this);
        var rowAffecteds = await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
        audit.PostSaveChanges();

        if (audit.Configuration.AutoSavePreAction != null)
        {
            audit.Configuration.AutoSavePreAction(this, audit);
            await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
        }

        return rowAffecteds;
    }

}

Erreur sur AuditEntries.AddRange(audit.Entries) : CS1503 Argument 1: impossible de convertir System.Collections.Generic.List<Z.EntityFramework.Plus.AuditEntry> en System.Collections.Generic.IEnumerable<DA.Systems.Focus.Data.EntityFramework.FocusOrm.AuditEntry>

Est-ce que je manque quelque chose?

Réponse acceptée

Vous utilisez Database First.

La classe AuditEntry de EF + n'est pas identique à celle générée par votre contexte.

Vous devez Import valeur.

AuditManager.DefaultConfiguration.AutoSavePreAction = (context, audit) =>
{
    // ADD "Where(x => x.AuditEntryID == 0)" to allow multiple SaveChanges with same Audit
    var customAuditEntries = audit.Entries.Select(x => Import(x));
    (context as Entities).AuditEntries.AddRange(customAuditEntries);
};

using (var ctx = new Entities())
{
    Audit audit = new Audit();
    audit.CreatedBy = "ZZZ Projects"; // Optional

    ctx.Entity_Basic.Add(new Entity_Basic() {ColumnInt = 2});
    ctx.SaveChanges(audit);
}

public AuditEntry Import(Z.EntityFramework.Plus.AuditEntry entry)
{
    var customAuditEntry = new AuditEntry
    {
        EntitySetName = entry.EntitySetName,
        EntityTypeName = entry.EntityTypeName,
        State = (int)entry.State,
        StateName = entry.StateName,
        CreatedBy = entry.CreatedBy,
        CreatedDate = entry.CreatedDate
    };

    customAuditEntry.AuditEntryProperties = entry.Properties.Select(x => Import(x)).ToList();

    return customAuditEntry;
}

public AuditEntryProperty Import(Z.EntityFramework.Plus.AuditEntryProperty property)
{
    var customAuditEntry = new AuditEntryProperty
    {
        RelationName = property.RelationName,
        PropertyName = property.PropertyName,
        OldValue = property.OldValueFormatted,
        NewValue = property.NewValueFormatted
    };

    return customAuditEntry;
}




Sous licence: CC-BY-SA
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi