Entity framework delete/update without round trip to the database

One of Entity Framework’s main advantage is the ability to load and track it’s graph. By default, code-first loads and tracks entities, whether they are in a single-tier or n-tier app. This comes at a cost of performance. Tracking entities can be just a little intensive on memory if we are loading thousands of records from the database. If we do not need the benefit of tracking, we may work with detached entity objects.

Updating

We’ll look at updating by ID of a detached entity.

[codesyntax lang=”csharp”]

        public User UpdateUser(User user, IEnumerable<Expression<Func<User, object>>> properties)
        {
            if (string.IsNullOrEmpty(user.UserId))
            {
                throw new InvalidOperationException("user does not exist");
            }
            else
            {
                db.Users.Attach(user);
                foreach (var selector in properties)
                {
                    string propertyName = Helpers.PropertyToString(selector.Body);
                    db.Entry(user).Property(propertyName).IsModified = true;
                }
                db.SaveChanges();
            }
            return user;
        }

[/codesyntax]

This is my normal update structure for an entity located in my repository. We pass the user entity (which is detached, can be generated from scratch), we check to make sure we have the ID. We then attach it to the graph. properties is a list of expressions parameters that we can pass to the method to tell EF what property to update. Note: This method of using expressions is known to be slightly slow because of parsing the expression tree. This way, we can update just the properties we want to change. We loop through the expression, convert the body of a selector in the expression to the property name, then set it to being modified. This is 1 database call.

Calling this would look like:

[codesyntax lang=”csharp”]

userRepo.UpdateUser(user, new Expression<Func<User, object>>[]
                                                {
                                                    m => m.Name
                                                });

[/codesyntax]

This is just updating the Name property for the user.

Deleting

This is the best one, deleting a user without a round trip. Simple and straight forward, create the object with the id, attach it, delete it.

[codesyntax lang=”csharp”]

var user = new User() { UserId = userId };
db.Users.Attach(user);
db.Users.Remove(user);
db.SaveChanges();

[/codesyntax]

Note: Attach is different from adding a new record to the database. We are attaching it to the EF graph.

Reading

If we are going the memory efficient way, we will have to load our entities without tracking.

[codesyntax lang=”csharp”]

IQueryable<User> query = db.Users.AsNoTracking();

[/codesyntax]

I return IQueryable<T> from my repository, so this is what I basically return. Although my Get method has some additional features, such as accepting an expression that will contain navigational properties to load up.

So in concluding, this is a trade-off between performance and code design. This is exactly why the framework team decided to include these methods, some system design requires us to take things into our own hands and work closer to metal (not too close [SQL]).

If anyone sees anything wrong in my post, please comment and tell. I’m still learning.