Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logging every data change with Entity Framework

There is a need from a customer to log every data change to a logging table with the actual user who made the modification. The application is using one SQL user to access the database, but we need to log the "real" user id.

We can do this in t-sql by writing triggers for every table insert and update, and using context_info to store the user id. We passed the user id to a stored procedure, stored the user id in the contextinfo, and the trigger could use this info to write log rows to the log table.

I can not find the place or way where or how can I do something similar using EF. So the main goal is: if I make a change in the data via EF, I would like to log the exact data change to a table in a semi-automatic way (so I don't want to check for every field for change before saving the object). We are using EntitySQL.

Unfortunately we have to stick on SQL 2000 so the data change capture introduced in SQL2008 is not an option (but maybe that's also not the right way for us).

Any ideas, links or starting points?

[Edit] Some notes: by using ObjectContext.SavingChanges eventhandler, I can get the point where I can inject the SQL statement to initialize the contextinfo. However I cannot mix the EF and the standard SQL. So I can get the EntityConnection but I cannot execute a T-SQL statement using it. Or I can get the connection string of the EntityConnection and create an SqlConnection based on it, but it will be a different connection, so the contextinfo will not affect the save made by the EF.

I tried the following in the SavingChanges handler:

testEntities te = (testEntities)sender; DbConnection dc = te.Connection; DbCommand dcc = dc.CreateCommand(); dcc.CommandType = CommandType.StoredProcedure; DbParameter dp = new EntityParameter(); dp.ParameterName = "userid"; dp.Value = textBox1.Text; dcc.CommandText = "userinit"; dcc.Parameters.Add(dp); dcc.ExecuteNonQuery(); 

Error: The value of EntityCommand.CommandText is not valid for a StoredProcedure command. The same with SqlParameter instead of EntityParameter: SqlParameter cannot be used.

StringBuilder cStr = new StringBuilder("declare @tx char(50); set @tx='"); cStr.Append(textBox1.Text); cStr.Append("'; declare @m binary(128); set @m = cast(@tx as binary(128)); set context_info @m;");  testEntities te = (testEntities)sender; DbConnection dc = te.Connection; DbCommand dcc = dc.CreateCommand(); dcc.CommandType = CommandType.Text; dcc.CommandText = cStr.ToString(); dcc.ExecuteNonQuery(); 

Error: The query syntax is not valid.

So here I am, stuck to create a bridge between Entity Framework and ADO.NET. If I can get it working, I will post a proof of concept.

like image 976
Biri Avatar asked Nov 17 '08 14:11

Biri


People also ask

How do I track changes in Entity Framework?

Tracking from queriesEF Core change tracking works best when the same DbContext instance is used to both query for entities and update them by calling SaveChanges. This is because EF Core automatically tracks the state of queried entities and then detects any changes made to these entities when SaveChanges is called.

Is EF core faster than EF6?

EF Core 6.0 performance is now 70% faster on the industry-standard TechEmpower Fortunes benchmark, compared to 5.0. This is the full-stack perf improvement, including improvements in the benchmark code, the . NET runtime, etc. EF Core 6.0 itself is 31% faster executing queries.

What does AsNoTracking do in Entity Framework?

The AsNoTracking() extension method returns a new query and the returned entities will not be cached by the context (DbContext or Object Context). This means that the Entity Framework does not perform any additional processing or storage of the entities that are returned by the query.

Should I use EF6 or EF core?

Keep using EF6 if the data access code is stable and not likely to evolve or need new features. Port to EF Core if the data access code is evolving or if the app needs new features only available in EF Core. Porting to EF Core is also often done for performance.


1 Answers

How about handling Context.SavingChanges?

like image 90
Craig Stuntz Avatar answered Sep 21 '22 03:09

Craig Stuntz