user11657764
user11657764

Reputation:

How to figure out which field has changed in a table? in C# with Entity Framework

In a table of fields a, b, c, d, ..., then user x changes the value of c, d, all field values ​​override and the values ​​of c and d are changed, the history I want From this system is that :

User x has changed the value of c and d at the same time, displaying both the new and the old values, and the same for other users.

If the user just edited but no changes were made to the fields, nothing would have happened.

And in order to figure out which fields have changed now, all fields have to be conditioned, or is there a library in C# to figure out which fields have changed now?

If this is a library an example of it is a great help.

Upvotes: 3

Views: 5414

Answers (3)

Edney Holder
Edney Holder

Reputation: 1228

I have done this many times. It is much easier to implement on the database side with a trigger.

create table Customer
(
    CustomerId integer Identy(1,1) primary key,
    CustomerFirstName nvarhar(25),
    CustomerLastName nvarchar(25),
    CustomerAdd1 nvarchar(50),
    CustomerAdd2 nvarchar(50)
)

create table ChangeAudit
(
    AuditId integer Identy(1,1) primary key
    ChangeDt datetime,
    ChangeTable nvarchar(50),
    ChangeField nvarchar(50),
    OldValue nvarchar(max),
    NewValue nvarchar(max),
    ChangedBy nvarchar(50)
)

create trigger CustomerAudit on Customer
after update, insert
as
begin
    if update(CustomerFirstName)
    begin
        insert into ChangeAudit(ChangeDt,ChangeTable,ChangeField,OldValue,NewValue,ChangedBy)
        select getdate(),'Customer', 'CustomerFirstName',d.CustomerFirstName,i.CustomerFirstName,SUSER_SNAME()
        from Customer c,
        inner join inserted i on t.CustomerId = i.CustomerId
        inner join deleted d on t.CustomerId = d.CustomerId
    end

    if update(CustomerLastName)
    begin
        insert into ChangeAudit(ChangeDt,ChangeTable,ChangeField,OldValue,NewValue,ChangedBy)
        select getdate(),'Customer', 'CustomerLastName',d.CustomerLastName,i.CustomerLastName,SUSER_SNAME()
        from Customer c,
        inner join inserted i on t.CustomerId = i.CustomerId
        inner join deleted d on t.CustomerId = d.CustomerId
    end
end

Upvotes: 3

Lutti Coelho
Lutti Coelho

Reputation: 2264

You can use the ChangeTracker class for discovery what was changed. You will need to use reflection to find the properties names of each modified entity.

foreach (var entry in db.ChangeTracker.Entries().Where(entry => entry.State == EntityState.Added || entry.State == EntityState.Modified))
{
    // Gets all properties from the changed entity by reflection.
    foreach(var entityProperty in entry.Entity.GetType().GetProperties())
    {
        var propertyName = entityProperty.Name;
        var currentValue = entry.Property(propertyName).CurrentValue;
        var originalValue = entry.Property(propertyName).OriginalValue;
    }
}

You can find more information about the ChangeTracker in this site: https://www.entityframeworktutorial.net/change-tracking-in-entity-framework.aspx

Upvotes: 3

Thomas Koelle
Thomas Koelle

Reputation: 3742

If you use EF as intended then you can find most in the changetracker before you commit.

_entities.ChangeTracker.Entries()
            .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified)
            .ToList();

EF don't do a database call unless something actually is updated

Upvotes: 1

Related Questions