Entity Framework 6 Extensions

Image for post
Image for post

Entity Framework 6 was and still remains a ‘workhorse’ for data access in corporate .NET-based applications primarily because of its stability, low barrier of entry and wide renown. Therefore, I hope this article will still be useful.

Database First Without EDMX

I really don’t want to go into the old debate on Code First vs. Database First. Instead, I’d better write a few words on how to make your life easier, if you prefer Database First. Many developers who prefer this approach complain about inconveniences when working with the tedious EDMX file. This file can turn team development into real hell: it significantly slows down the merge of parallel changes because of the permanent ‘mixing’ of its internal structure. As for the models with several hundreds of instances (a typical legacy monolith), you can face a strong speed slowdown of any action when working with the standard EDMX designer.

The solution seems to be quite obvious — you need to abandon EDMS and prefer an alternate mean of the POCO generation and metadata storage. Well, it looks like a simple task, and EF has the Generate Code First From Database feature that is viable in Visual Studio (inVS2015 for sure). But in real life, rolling database changes onto the received model is very inconvenient with this tool. Furthermore, everyone working with EF for a long time remembers the Entity Framework Power Tools extension, that solves similar problems, but unfortunately, this project seems to be almost dead (you cannot install it on VS2015 without hacking), and a part of its developers now works in the EF team.

When everything looked so bad, I found EntityFramework Reverse POCO Generator. It is a T4 template for the POCO generation on the basis of the existing DB with a large number of settings and the open source code. It supports all basic EDMX features and includes a range of additional tips: generation of FakeDbContext/FakeDbSet for unit testing, attribute coverage for models (e.g. DataContract/DataMember) and others. Also, T4 provides a full control over code generation. To sum up: it works consistently, the team enjoys it, and migration of existing projects goes smoothly.

Working with Detached Graphs

Usually, attaching a new object or an object that was previously generated in other context is a simple task. Problems begin when it comes to graphs, that is entities with links: EF ‘out of the box’ does not track changes in the content of navigation properties of an entity reattached to the context. To track changes, the corresponding entry must exist (an object with service information, including info about the state of entity — Added, Modified, Deleted, etc) for each object entity during the life-cycle of the context. You can fill entries for adding graph in the following 2 ways:

  1. You can store the state within the entities and track changes on your own. Thus, our detached graph will contain all information required for connection.
  2. You can do nothing beforehand, and when you attach a graph to the context, you need to pull up the source graph from DB and set the entity states basing on the comparison of two graphs.

An example of solution #1 can be found in the Pluralsight course from Julie Lerman, a renown EF expert. You will need to take a large number of steps for its implementation. All entities must implement the IstateObject interface:

public interface IStateObject
{
ObjectState State { get; set; }
}

One way or another, we need to ensure the relevancy of the State values after manual addition of each graph entity to the context

context.Foos.Attach(foo);

in order to pass through all entries by editing their states:

IStateObject entity = entry.Entity;
entry.State = ConvertState(entity.State);

In this case, we won’t need additional DB calls, but solution turns out to be too jumbo, fragile, and potentially not working for the many-to-many relations. Besides, it lumbers models (by the way, the requirement of interface implementation can be extended with modification of the T4 templates from the previous section of this article).

Let’s consider solution #2 briefly:

context.UpdateGraph(root, map => map.OwnedCollection(r => r.Childs));

This call will add the root entity to the context. At that, it will update the navigation property with the Childs objects collection by means of a single SELECT to DB. It is now possible owing to the GraphDiff library. The author of the library has made all the dirty work and fixed basic bugs.

Continue reading the article here https://goo.gl/eaEsP8 where we uncovered the following questions as well:

Thanks for reading!

Written by

Awesome blog focused on databases and Microsoft, .NET and cloud technologies. http://codingsight.com/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store