Entity Framework Performance Tips
- Long running contexts are a performance killer. EF already caches anything that can be reused when it starts up the first time. There is nothing you are saving here except a few lines of code, and it's not worth it - you can find yourself with slow performance, memory and locking problems.
- Example
using(var context = new EFContext())
{
entities = context.Entities.Where(x => x.Name == "Example").ToList();
// ... some long running operation to do with entities
widgets = context.Widgets.Where(x => entityIds.Contains(x.EntityId)).ToList();
}
- This optimisation allows you to tell Entity Framework not to track the results of a query. This means that Entity Framework performs no additional processing or storage of the entities which are returned by the query. However it also means that you cant update these entities without reattaching them to the tracking graph.
- Example : IQueryable<Student> filteredData = dbSchool.Student.AsNoTracking();
Avoid loading full objects
- Continuing with the read-only theme, if you only need a couple of values from each row then just Select() what you need. This instructs EF to only request those columns from SQL, therefore avoiding loading the full object as well as context tracking.
- Example
using (var context = new EFContext())
{
info = context.Entities.Select(x => new SomeInfo
{
Name = x.Name,
Address1 = x.Address1,
Address2 = x.Address2
}).ToList();
}
Avoid Eager Loading
What is Eager loading ?
- Eager loading is the process whereby a query for one type of entity also loads related entities as part of the query. Eager loading is achieved using the Include() method.
- Example
var res = (from s in context.Students.Include("Standard")
where s.StudentName == "Student1"
select s).FirstOrDefault();
When to Use Eager Loading ?
- In "one side" of one-to-many relations that you sure are used every where with main entity.
Avoid Lazy Loading
What is Lazy Loading ?
- Lazy loading is the process whereby an entity or collection of entities is automatically loaded from the database the first time that a property referring to the entity/entities is accessed. Lazy loading is by default in Entity Framework means delaying the loading of related data.
- Example to avoid it
using (var ctxDb = new SomeCtx())
{
ctxDb.Configuration.LazyLoadingEnabled = false;
var result = from s in ctxDb.Students.Include("Address")
select s;
result = result.OrderByDescending(m => m.id).ThenBy(s => s.Name);
return result.ToList();
}
Remove extra save processing time for add
- If you are simply adding a number of objects then saving them, you may not be aware that EF will check whether each of those new objects has changed.
- To avoid this, turn off AutoDetectChangesEnabled before adding, then back on again afterwards. It does exactly what its name suggests.
- Example
using (var context = new EFContext())
{
context.Configuration.AutoDetectChangesEnabled = false;
// Your code
context.SaveChanges();
}
Speed up bulk Add
- There isn't used to be a convenience method for adding a collection of objects from to the database at once. The only way was a loop and calls to Add(),
- Solution : Entity Framework 6.0
- Example
public static void DeleteStudents( List<Student> ListStudent)
{
using (var dbCntx = new SchoolDb())
{
dbCntx.Students.AddRange(ListStudent);
SaveChanges();
}
}
Speed up bulk deletes
- There isn’t used to be a convenience method for deleting a collection of objects from the database at once. The only way was a loop and calls to Remove(), which you guessed it, hit the database on every iteration.
- Solution : Entity Framework 6.0
- Example
public static void DeleteStudents( List<Student> ListStudent)
{
using (var dbCntx = new SchoolDb())
{
dbCntx.Students.RemoveRange(ListStudent);
SaveChanges();
}
}
Avoid Sorting by string / char / varchar type column for default list loading.
- Use int, numeric type for sorting.
- During database design if possible add indexes property to column which can be used as search parameter in Application.
- Avoid sorting by Date Time
Use the Latest Entity Framework available and supported by Visual studio
- Entity Framework is in continuous developement and optimization process by the Microsoft.
Be careful using IQueryable
- Returning an EF query as IQueryable<T> from a method is handy because it lets you build on the query later.
- Then there is the effect of looping through an IQueryable, which can cause EF to execute a separate query hit to SQL Server for each iteration.
- Example : IQueryable<Episode> filteredData = dbAfib.Episodes.AsNoTracking();
Tool available to check Performance
- LinqPad
- SQL Profiling
- Code Profiling
No comments