Logging changes through Entity Framework - entity-framework

Can anyone direct me to a good strategy for implementing change tracking in my Entity Framework model?
I have around 20 entities to track changes on (accessed via facades / unit of work) and I need to be able to display who changed what when on displaying the record in the UI.
I know there's Context.OnSavingChanges (or whatever it's called) but I'd probably want to access the changes in queries like context.MyEntity.ChangeLog
Must I create a ChangeLog entity, add associations to all the entities or is there a better via via savingchanges?
Richard
P.s. Have a great weekend!

Entity framework is ORM = API responsible for persistence and loading from database. What you persist or load is completely up to you so if you want change tracking you must to code it.
The most common approach is indeed using OnSavingChanges or overriding SaveChanges because you are usually saving changed executed by single user.

An old question but for anyone looking for auditing changes on EF >= 6 or EF Core, I worked on an open source library Audit.EntityFramework you could try.

See FrameLog, which is an open source library I wrote for this purpose. You call it from SaveChanges and it deals with the rest, including giving you a strongly-typed API for querying the logs.

Related

Getting familiar with Entity Framework when using existing database

We are currently rewriting an existing internal ASP.NET Web Forms application. Our application consists of a Web Api back end which uses Entity Framework 6 for data access and an front end which uses AngularJS.
We have an existing large database that I've created EF models using the Code-First Using Existing Database method and we are using data transfer object classes as inputs/outputs to our API methods so we aren't directly exposing our model classes. So basically, I'm trying to become proficient with EF, Web Api and AngularJS all at the same time. For the most part I'm fairly comfortable with the latter two, but for EF I haven't completely gotten comfortable with. I've watched a lot of the videos on Microsoft Virtual Academy but this is the first time I've had some hands-on experience with it.
We've been working on this application for a few months and so far we've only had to work with CRUD operations on our entities (POCO DTO's) which are flat objects with simple properties. However, we've finally come across some situations where we need to deal not only with our classes, but properties which are classes themselves; a parent-child relationship.
Therefore, I have the following questions:
I see that when we have a proper foreign key relationship in our DB, that virtual properties are created in EF, which from what I recall are to support lazy-loading. However, lazy-loading isn't really feasible in this environment where we are using web services (Web Api). Our object model does allow for some really large hierarchy of classes where a fully populated object and its children would mean a large amount of data would be passed around when that really isn't necessary, so in most cases a first level object is all we need. In some cases however, we do want to populate child classes, so my question is how do we do that, and where do we do that? I've looked at the automatically-generated code in the DB Context but we have also used scaffolded code to create our controllers. Which place do we need to do this? I've seen code samples showing how do to this but it hasn't said specifically where this code lies. It appears to be within a controller but I could be wrong.
If we do allow for 2- or more level hierarchy of objects, does EF automatically handle operations (updates, deletes, etc.) -- for example, if we have a "Company" object which has a collection of "Customer" objects, and we delete the "Company" object, do the related "Customer" objects get deleted too? Also, is a multi-step operation like that automatically performed within a transaction or do we need to explicitly set that up?
If I modify a model class or the DB context, seeing as this code is automatically-generated, that's generally bad practice as my changes could be overwritten, so I am assuming the controller code is where I want to make my changes. I am aware of database migrations but I have no experience with them and I am sure I'll need to use them at some point because I am fairly confident that our database may not have all the foreign key relationships necessary for EF to do everything we need at the moment.
I know this is a long post, but if anyone can give some guidance on how to do some of these things because it's not only me that's having to deal with this but I have two other developers on my team who are working on this project and we are all as inexperienced with this as the others are. Thanks
For the purpose of sending data across a web service, I'd suggest creating a DTO to hold the data you want to send and mapping your entities to the DTO instead of trying to send the entities themselves in your payload. It also protects your API from changes to your entity.
Cascading deletes are configurable, iirc, but I'm not 100% sure what the default is. Transactions are generally not implicit, so you will want to use those where you require them.
Not exactly sure what you are asking here. In general, how your entities/tables change depends on if you are using database-first or code-first. If you are using database-first (you will have a .edmx file in your solution that has the model matching your schema), you just update the SQL directly and update your entity model via the .edmx. If you use code-first, you will change the entities how you want them and run a database migration to update your database to match.
MSDN article about code-first migration: https://msdn.microsoft.com/en-us/data/jj591621.aspx

Caching with entity framework 6 and get notified when something changed

Lets say that querying certain scenarios takes some time. For example to get a certain entity I have to make a join of several tables. Is there a way to cache the result and when something changed in the entity that cache get destroyed?
I can do this manually but as you want to cache more this becomes tedious to maintain.
Is there a way to automate this with entity framework? My ultimate goal is query an entity and that goes to the cache then if it is not there it will get it from the database else it will return it from the cache, if something changed in that entity then it will be removed from the cache.
I want this to be implemented without me caring about checking the cache and let that library do this behind the scene, i.e. the whole scenario is abstracted to me by simply querying an entity.
Is there a library/technique that can implement this?
I am using EF6, Sql Server, ASP.NET MVC
This is called second level caching. I want to implement this too. As far as I know this is not supported by EF6. I have seached the internet a lot and find some solutions, but they are tedious to implement. The easy way is to use a solution like NCache (both commercial and free).

EntityFramework - Use Entities in Modules without access to the Database

I'm currently creating an application which is highly modular (using the Prism-Framework) and accesses a database via the EntityFramework implemented in CodeFirst.
My goal is to seperate the actual writing of the data into the Database from the "normal" use of the created Entities. Writing to the Database shall only be done by the main-Application but the Modules should still be able to use the Entity-Classes.
Thus, they must know the DataContext or at least the Entiy Classes. Here is the problem, though: If a module changes a property of an Entity Class and the main-Application calls "SaveChanges()" on the DataContext for some other reason, the changes made by the module are automatically saved to the Database without the main-Application having control over it.
How can I prevent this behaviour? The Modules must not be able to change the Database-Content, except via a defined Interface to the main-Application.
My first thought was to implement ICloneable in every entity-Class and to only pass clones of the Entity-Objects to the Modules to work with. The modules would then, if they wanted to request a change in the database, pass the cloned Objects to the main-Application which updates the original object and calls "SaveChanges()" on the DataContext.
Do you guys think this is a viable solution, or might there be a better way to implement this behaviour?
Thanks in advance!
Use the DbSet.AsNoTracking() Method to enable reading data from the database that will not be tracked by the DbContext.

Entity Framework Code First - Can an existing table be mapped and made read only?

I need to use the users table from a parent site, is it possible to map the user table using the fluent API and have it be read only?
In case of EF code first you can't directly make it "read-only" but you can design your code to not expose DbContext and related DbSet outside of your DAL logic so rest of the application cannot add a new user.
In case of EDMX based mapping you can make it read only by mapping it as a custom SQL query (or database view) where insert, update and delete operations are not supported until you map them custom SQL commands or stored procedures.
According to a comment on ScottGu's blog, no.
Right now we don’t support read-only (or semi-read-only) properties in
Code First but this is an interesting suggestion that I will talk with
our design team about. In general the Entity Framework doesn’t have
support for marking something as “read-only” so we may have to wait
for another major .NET framework release to get this working. For now,
you will have to add business logic in your entity to allow the
property to be set only once.
Jeff Derstadt
Entity Framework Code First Team

Is there an easy way to use ASP.NET caching with Entity Framework 4.1 Code First?

We are using EF code first with the App Fabric cache on Windows Azure (although, I think the question is really more generic since we are using it as an ASP.net caching provider). Is there an easy way to enable caching of DBset objects? Our db is small and not updated very frequently, so ideally we could cache the entire database in memory, and use some ttl expiry to refresh object sets. Any advise from someone with experience caching using EF code first would be great.
Don't do that. If you want to cache data, extract them to separate Lists and cache them separately. Caching DbSet means caching DbContext which I would promote to anity-pattern in Entity framework. Problems with identity map and unit of work are described in linked answer. Another problem is that there is no real refresh. If you really want to refresh data you must dispose context and create a new one. Context is also not thread safe so sharing it among multiple requests can cause unexpected results.
Maybe you could use this solution, but I never used it with Azure:
EF Caching Provider