Coder Social home page Coder Social logo

I need help with EF Core about audit.net HOT 9 CLOSED

BogdanJak avatar BogdanJak commented on June 3, 2024
I need help with EF Core

from audit.net.

Comments (9)

thepirat000 avatar thepirat000 commented on June 3, 2024

Try replacing the .UseDbContext<ApplicationDbContext>() line with this:

.UseDbContext(ev => ev.EntityFrameworkEvent.GetDbContext().GetService<ApplicationDbContext>())

So the ApplicationDbContext instance is resolved from the IServiceProvicer.

Another way is to supply the ApplicationDbContext constructor parameters, in your case the DbContextOptions<AuditDbContext>, for example:

.UseDbContext<ApplicationDbContext>(new DbContextOptionsBuilder<ApplicationDbContext>().UseSqlServer(connectionString).Options)

from audit.net.

BogdanJak avatar BogdanJak commented on June 3, 2024

Hi Federico

Thanks - it works. Your library is great.

But I have one more question.

I save all changes in the AuditLog table. Is it possible to save only the changed data values in a separate table, e.g. AuditLogChanges.
In this table I would like to save values from ChangeObject.
It would be good if the AuditLogVhanges table was related to the AuditLog table.

Is it even possible?

Bogdan

from audit.net.

thepirat000 avatar thepirat000 commented on June 3, 2024

Can you elaborate a little bit more? maybe sharing the auditlog / auditlogchanges schema you have in mind

from audit.net.

BogdanJak avatar BogdanJak commented on June 3, 2024

My current AuditLog class

`public class AuditLog
{
public Guid Id { get; set; }
public string? TableName { get; set; }
public string? TableName1 { get; set; }
public string? AuditAction { get; set; }
public DateTime AuditDate { get; set; }
public string? AuditUserName { get; set; }
public int Duration { get; set; }
public string? EventType { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public string? Type { get; set; }
public string? DatabaseName { get; set; }
public string? Changes { get; set; }

}`
The planned AuditLogChanges class

public class AuditLogChanges { public Guid Id { get; set; } public Guid AuditLogId { get; set; } public string? ColumnName { get; set; } public string? OriginalValue { get; set; } public string? NewValue { get; set; } }
Related one-to-many AuditLog.Id -> AuditLogChanges.AuditLog.Id

My current configuration

`Audit.Core.Configuration.Setup()
.UseEntityFramework(ef => ef
.UseDbContext(new DbContextOptionsBuilder().UseSqlServer(connectionString).Options)

            .AuditTypeExplicitMapper(map => map
                .Map<Players, AuditLog>((players, audit) =>
                {
                    audit.TableName = "Players";
                    
                })
                .Map<Positions, AuditLog>((players, audit) =>
                {
                    audit.TableName = "Positions";

                })
                .AuditEntityAction<AuditLog>((evt, entry, audit) =>
                {
                    audit.TableName1 = entry.Table.ToString();
                    audit.AuditDate = DateTime.UtcNow;
                    audit.AuditAction = entry.Action;
                    audit.AuditUserName = evt.Environment.UserName;
                    audit.Duration = evt.Duration;
                    audit.EventType = evt.EventType;
                    audit.StartDate = evt.StartDate;
                    audit.EndDate = evt.EndDate;
                    audit.Type = evt.EventType;
                    audit.DatabaseName = evt.GetEntityFrameworkEvent().Database;
                    audit.Changes = entry.ToJson();
                    

                }))
            .IgnoreMatchedProperties(true));`

Ultimately, I would like to create an audit manager in which I could show the changed values in individual columns of the table.

from audit.net.

BogdanJak avatar BogdanJak commented on June 3, 2024

A new problem
I am getting the following error while updating a record in the database

image
Audit.zip

Bogdan

from audit.net.

thepirat000 avatar thepirat000 commented on June 3, 2024

Not sure if I'm understanding your use case, but assuming you want to audit entities to two tables; one for the table audit and another one for the column values, then you can use the AuditTypeMapper with a common entity action.

For example, I'm simplifying your audit tables to something like this:

// This table stores an action performed to a table (insert, update or delete)
[AuditIgnore]
public class AuditLogTable
{
    [Key]
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public string User { get; set; }
    public string Table { get; set; }
    public string Action { get; set; }
    public ICollection<AuditLogColumn> Columns { get; set; }
}

// This table stores the column values for the AuditLogTable entity
[AuditIgnore]
public class AuditLogColumn
{
    [Key]
    public int Id { get; set; }
    public int AuditLogTableId { get; set; }
    public string Column { get; set; }
    public string OldValue { get; set; }
    public string NewValue { get; set; }
}

Note the [AuditIgnore] attribute for the audit entities, this is to avoid auditing the audit table and generating an infinite loop.

So you can configure the EF Data Provider as follows:

Audit.Core.Configuration.Setup()
    .UseEntityFramework(e => e
        .AuditTypeMapper(_ => typeof(AuditLogTable))
        .AuditEntityAction<AuditLogTable>((ev, entry, auditEntity) =>
        {
            auditEntity.User = ev.Environment.UserName;
            auditEntity.Date = ev.StartDate;
            auditEntity.Action = entry.Action;
            auditEntity.Table = entry.Table;
            auditEntity.Columns = MapColumns(entry);
        })
        .IgnoreMatchedProperties(true));

//..
public static List<AuditLogColumn> MapColumns(EventEntry entry)
{
    if (entry.Changes != null)
    {
        return entry.Changes
            .Select(c => new AuditLogColumn()
            {
                Column = c.ColumnName, 
                OldValue = c.OriginalValue?.ToString(), 
                NewValue = c.NewValue?.ToString()
            }).ToList();
    }
    else
    {
        return entry.ColumnValues
            .Select(c => new AuditLogColumn()
            {
                Column = c.Key,
                NewValue = c.Value?.ToString()
            }).ToList();
    }
}

Hope it helps

from audit.net.

BogdanJak avatar BogdanJak commented on June 3, 2024

It helped, and it helped a lot
Yes, that's what I meant. Your code works very well. Thank you very much.

Have you looked at the error I get when editing a record in the database? My sample attached in previous message.

from audit.net.

thepirat000 avatar thepirat000 commented on June 3, 2024

Not sure why it's throwing that exception, but note you are wrongly configuring your DB context for auditing.

If you inherit your DB context from AuditDbContext or AuditIdentityDbContext, then you should NOT override the SaveChanges nor use the DbContextHelper.

You are mixing 1. and 2. from the high-level save changes interception

from audit.net.

thepirat000 avatar thepirat000 commented on June 3, 2024

Closing this for inactivity. Assuming the issue was solved. Of you're still having this issue please comment below

from audit.net.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.