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

audit entity-framework-6 entity-framework-plus

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:

CREATE TABLE [dbo].[AuditEntries] (
    [AuditEntryID] [int] NOT NULL IDENTITY,
    [EntitySetName] [nvarchar](255),
    [EntityTypeName] [nvarchar](255),
    [State] [int] NOT NULL,
    [StateName] [nvarchar](255),
    [CreatedBy] [nvarchar](255),
    [CreatedDate] [datetime] NOT NULL,
    CONSTRAINT [PK_dbo.AuditEntries] PRIMARY KEY ([AuditEntryID])
)

GO

CREATE TABLE [dbo].[AuditEntryProperties] (
    [AuditEntryPropertyID] [int] NOT NULL IDENTITY,
    [AuditEntryID] [int] NOT NULL,
    [RelationName] [nvarchar](255),
    [PropertyName] [nvarchar](255),
    [OldValue] [nvarchar](max),
    [NewValue] [nvarchar](max),
    CONSTRAINT [PK_dbo.AuditEntryProperties] PRIMARY KEY ([AuditEntryPropertyID])
)

GO

CREATE INDEX [IX_AuditEntryID] ON [dbo].[AuditEntryProperties]([AuditEntryID])

GO

ALTER TABLE [dbo].[AuditEntryProperties] 
ADD CONSTRAINT [FK_dbo.AuditEntryProperties_dbo.AuditEntries_AuditEntryID] 
FOREIGN KEY ([AuditEntryID])
REFERENCES [dbo].[AuditEntries] ([AuditEntryID])
ON DELETE CASCADE

GO

Je reçois une erreur dans le constructeur statique:

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);
}

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;
}


Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow