Hello!
In this publication I want to share my personal experience of using the Entity Framework (EF) in a real application and give some useful tips on using this framework.
I have been developing enterprise applications on the .NET platform for more than 7 years, during this time I tried several ORM libraries, but now I use the Entity Framework First for new projects.
Initially, as the name suggests, this approach assumed that the database storing the application data is described first with the help of code, and then the framework itself creates or updates it. However, many developers have chosen to use the opposite approach, when the database is first created and then objects are sent to it. This is especially convenient for enterprise applications, where data is almost always put at the forefront and uses a fairly advanced DBMS such as Oracle or MSSQL Server. I don’t like the EF designer when there are more than a hundred tables in it. Therefore, Code First was taken personally by me as something incredibly convenient and extremely useful.
')
Once again I want to repeat that, in my opinion, in an enterprise application, the main thing is data, not your application. Applications come and go, are replaced with newer ones, and the data remains and is used for years. Therefore, in any of my applications, the database is always created by the database designer, and not by my application.
The first thing to do if you already have a database ready is to create classes that correspond to the tables. Manually doing this is very tiring, therefore:
Council number 1. Table-based class generation
The T-SQL script, which can be taken
from here , really works and is very convenient.
Council number 2. Pregeneration view
EF is known for the very long processing time of the first request for receiving and saving data. In order to correct this situation, you can use the view pregeneration.
The pregeneration view is something that happens inside the framework when the first request is executed. This process can be transferred to the stage of compiling your application, which will significantly reduce the speed of the first request. For different versions of EF, the methods are somewhat different. I used
this approach and was completely satisfied with it.
Council number 3. Bulk data update with DetectChanges
By default, the framework is configured to automatically track changes that must then be saved to the database.
For example, consider this simple example:
var dbContext = new MyDbContext(); // for(var i=0;i<1000;i++) { dbContext.People.Add(new Person());//!!! } // dbContext.SaveChanges();
When launching it, many will probably be surprised that most of the time will be spent not on the database query itself, but on inserting objects into dbContext itself. The fact is that when you change the data inside DbContext, there are a lot of checks and other little-studied things, more details about which can be found
here . To avoid this, you can turn off tracking of changes in the DbContext class, and then explicitly call the DetectChanges () method, which itself will detect these changes. So, this code will work much faster:
var dbContext = new MyDbContext(); // dbContext.Configuration.AutoDetectChangesEnabled = false; // for(var i=0;i<1000;i++) { dbContext.People.Add(new Person());// } dbContext.ChangeTracker.DetectChanges(); // . // dbContext.SaveChanges();
Council number 4. Keep track of the sql queries that the framework generates
This is quite universal advice, applicable, probably, to all ORM, but for some reason many people forget about it. And after the introduction of the application, opening the profiler and seeing 50 queries to the database to display a fairly simple form are extremely surprised.
Meanwhile, the framework offers mechanisms for some optimization. Among these mechanisms, the most well-known is the Include method, which “pulls” child objects in the same query. For example:
var dbContext = new MyDbContext();
Council number 5. Isolate database logic
Although the EF name contains the word “framework”, it can also be used as a regular library simply to simplify work with the database.
In most books and presentations, we see code similar to this:
// MVC public class PersonController: Controller { // EF AppDbContext dbContext; public PersonController(AppDbContext dbContext) { this.dbContext = dbContext; } public IActionResult ViewPerson(int id) { var person = dbContext.People.First(p=>p.Id == id); return View(person); } }
The problem with this code is that it tightly binds all parts of the application to the Entity Framework. This is neither good nor bad in itself, but at the same time you need to understand that you are significantly complicating your life if the data access architecture has to be changed. And there may be a lot of options:
- You suddenly find that a particular query is extremely slow and decide to replace it with a stored procedure or View
- You will be surprised to find how difficult it is to store data obtained in different DbContext
- You will be surprised to observe the TransactionScope, DbConnection classes inside the controller when you need a non-trivial data update logic.
- You will think about reusing code to work with the database
- You decide to use NHibernate instead of EF
- And why not use the SOA architecture, and not start receiving and saving data through web services?
I like the approach when EF is used ONLY within a project called DAL (DataAccess, etc.) in classes called Repository, for example:
// Person public class PersonRepository: IPersonRepository { public Person GetPerson(int personId) { var dbContext = new AppDbContext(); var person = dbContext.People.First(p=>p.Id == id); return person; } public void SavePerson(Person person) { var dbContext = new AppDbContext(); var dbPerson = dbContext.People.First(p=>p.Id == person.Id); dbPerson.LastName = person.LastName; ..... dbContext.SaveChanges(); return person; } }
This approach is good because your application will only know about your objects and how you can get them from the database and how to save them to the database. Believe me, this will make your life much easier.