mssqltips logo

Entity Framework Core Disconnected Entities with TrackGraph

By:   |   Updated: 2019-10-29   |   Comments   |   Related: More > Entity Framework

Problem

The TrackGraph method in Entity Framework Core (EF Core) can be used for handling complex data in disconnected scenarios. This article presents a discussion on how we can work with this method in EF Core.

Solution

Entity Framework Core provides the methods Add, Attach and Update that can be used for entity graph-traversal. While these methods work just fine in connected scenarios, you might often want to work in a disconnected mode and track the entire object graph. Here's exactly where the ChangeTracker.TrackGraph method comes in.

The TrackGraph method introduced in Entity Framework Core can be used to track an entire entity graph. The ChangeTracker.TrackGraph method is available as part of the Microsoft.EntityFrameworkCore.ChangeTracking namespace and is designed to work in disconnected scenarios. While the entities are retrieved using one instance of the data context, changes to those entities are saved to the persistent store using another instance of the data context.

Getting started

Follow the steps outlined in one of my previous articles to create a console application project in Visual Studio. I prefer using Visual Studio 2019 – the community version is available for free. If you don’t have a copy of Visual Studio 2019 installed in your system, you can download a copy.

You should also run the following commands at the Package Manager Console to install the necessary packages.

  • Install-Package Microsoft.EntityFrameworkCore
  • Install-Package Microsoft.EntityFrameworkCore.Tools
  • Install-Package Microsoft.EntityFrameworkCore.SqlServer

Modifying data in disconnected mode with Entity Framework Core

To track changes to an entity, Entity Framework Core takes advantage of a property called State that is attached to all entities that are tracked. This property is an enum of type EntityState. The following methods when used, change the EntityState of an entity in the entity graph.

  • Attach()
  • Entry()
  • Add()
  • Update()
  • Remove()

Entity Framework Core is adept at generating the SQL to be executed based on the current state of an entity graph. The change tracking feature works just fine in Entity Framework Core. Here's an example that illustrates this:

using (var context = new DemoDataContext())
{
    var author = context.Authors.Single(a => a.Id == 1);
    author.FirstName = "Joydip";
    author.LastName = "Kanjilal";
    context.SaveChanges();
}

Refer to the code example shown above. Note that the author entity is retrieved within the using block and the Entity Framework Core runtime starts tracking this entity immediately after the entity instance is created. When the SaveChanges method is called on the data context instance, the Entity Framework Core runtime checks to see if any changes have been made to the entity being persisted and generates the SQL statement as appropriate. In our example, the two properties FirstName and LastName were updated.

When working in the disconnected mode, you would need to explicitly let the context know that the entity has been modified. You can do this in several different ways. These include:

  • Setting the EntityState property
  • Using the DbContext.Update method
  • Using the DbContext.Attach method

Setting the EntityState property of the entity in Entity Framework Core

The state of an entity determines how the tracked entities will be processed when the SaveChanges method is called. An entity can be in any one of the following states:

  • Added
  • Unchanged
  • Modified
  • Deleted

The following code snippet illustrates how the EntityState property can be set to Modified.

public void Save(Article article)
{
    context.Entry(article).State = EntityState.Modified;
    context.SaveChanges();
}

Note that this approach will enable tracking for only the Article entity in this example. The related entities of the Article entity will not be tracked.

Calling the Update method on the data context instance in Entity Framework Core

The following code snippet illustrates how you can call the Update method.

public void Save(Article article)
{
    context.Update(article);
    context.SaveChanges();
}

While the Update method is used for one entity, you can use the UpdateRange method for several entities. A call to the Update method marks the entity being tracked as modified.

Using the Attach method in Entity Framework Core

When you call the Attach method on an entity, the state of the entity and all other reachable entities become Unchanged. You can explicitly set the IsModified property to true to ensure that the context is aware of the properties of the entity that have been changed. The following code snippet illustrates how this can be achieved.

var author = new Author {
    Id = 1,
    FirstName = "Joydip",
    LastName = "Kanjilal"
};
context.Attach(author);
context.Entry(author).Property("FirstName").IsModified = true;
context.Entry(author).Property("LastName").IsModified = true;

In this code example, both the properties FirstName and LastName are modified.

Working with the TrackGraph API in Entity Framework Core

Entity Framework Core provides support for tracking entities. The TrackGraph method introduced in Entity Framework Core provides an easy way to iterate a graph of objects that you would want to be tracked. You can take advantage of TrackGraph to access individual entities within an object graph and then execute customized code against each of the entities of the graph.

Creating the entity classes in Entity Framework Core

Consider the following entities named Author, Address and Article. Note that the Author entity contains a reference to the Address entity and to a list of article entities.

public class Author
    {
        public int Id {  get; set;  }
        public string FirstName {  get; set;  }
        public string LastName {  get; set;  }
        public Address Address {  get; set;  }
        public List<Article> Articles {  get; set;  }
    }
    public class Address
    {
        public int Id {  get; set;  }
        public string City {  get; set;  }
        public string Country {  get; set;  }
    }
    public class Article
    {
        public string Title {  get; set;  }
    }

Populate the entities with data in Entity Framework Core

We'll now examine how we can use the TrackGraph method. First off, let's populate the entities with some data. The following code example demonstrates how these entities can be populated with data. Note that the root entity is Author.

var author = new Author() 
{
    Id = 1,
    FirstName = "Joydip",
    LastName = "Kanjilal",
    Address = new Address()
    {
        Id = 1,
        City = "Hyderabad",
        Country = "India"
    },
    Articles = new List<Article>() 
      {
         new Article(){Title = "Mastering Entity Framework Core" },
         new Article(){Title = "Mastering ASP.NET Core Web API" }
      }
};

Using the TrackGraph method in Entity Framework Core

The following code snippet illustrates how the TrackGraph method can be used.

var context = new MSSQLTipsDataContext();
 
context.ChangeTracker.TrackGraph(author, a => {
 
         if (a.Entry.IsKeySet)
           {
              a.Entry.State = EntityState.Unchanged;
           }
         else
           {
              a.Entry.State = EntityState.Added;
           }
        });

Refer to the code snippet given above. If an entity has a key, the state of the entity is marked as "Unchanged". If an entity doesn’t have a key associated, the state of the entity is marked as "Added".

Lastly, the following code snippet shows how you can display the entity name and state of those entities that doesn't have a key.

foreach (var entry in context.ChangeTracker.Entries())
  {
     var entityName = entry.Entity.GetType().Name;
     var state = entry.State.ToString();
     Console.WriteLine($"Entity: {entityName}, State: {state}");
  }

References

Next Steps
  • The TrackGraph method in Entity Framework Core provides an easy way to iterate graph of objects, i.e., the root entity and all its related entities that you might want the context to keep track of.


Last Updated: 2019-10-29


get scripts

next tip button



About the author
MSSQLTips author Joydip Kanjilal Joydip Kanjilal - Microsoft MVP (2007 to 2012), Author and Speaker with more than 20 years of experience. Authored more than 500 articles, 8 books and reviewed a dozen books.

View all my tips




Post a comment or let the author know this tip helped.

All comments are reviewed, so stay on subject or we may delete your comment. Note: your email address is not published. Required fields are marked with an asterisk (*).

*Name
*Email
Email me updates

Signup for our newsletter

I agree by submitting my data to receive communications, account updates and/or special offers about SQL Server from MSSQLTips and/or its Sponsors. I have read the privacy statement and understand I may unsubscribe at any time.






download

























get free sql tips

I agree by submitting my data to receive communications, account updates and/or special offers about SQL Server from MSSQLTips and/or its Sponsors. I have read the privacy statement and understand I may unsubscribe at any time.



Learn more about SQL Server tools