Accessing Objects Just After they are Saved by Entity Framework

Download full source code.

In this post, I will show you how to access objects just after they are saved by Entity Framework, and have had a primary key assigned to them.

One scenario where you might want to do this is when you need to notify another part of your application that the save has happened, and include the primary key of the object that was saved. In a subsequent post, I will show how to use Mediatr to send and handle notifications right after the save happens.

But for now, I’m going to stick with a simple example.

The DbContext

I have a simple DbContext that has two DbSets, one for buyers, and one for sellers.

public BuyersSellersContext(DbContextOptions<BuyersSellersContext> options) : base(options) { }

public DbSet<Seller> Sellers { get; set; }
public DbSet<Buyer> Buyers { get; set; }

Everything is normal so far.

Next, I override the SaveChangesAsync method. But, rather than returning the result of base.SaveChangesAsync(..), I store the result in a variable and then use the ChangeTracker to get at the entities that were saved.

Using a little LINQ, I can filter the entities to separate the buyers and sellers.

public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
    var resultOfSave = await base.SaveChangesAsync(cancellationToken);
    var buyers = this.ChangeTracker.Entries().Where(ee => ee.Entity is Buyer).Select(ee => ee.Entity as Buyer);
    var sellers = this.ChangeTracker.Entries().Where(ee => ee.Entity is Seller).Select(ee => ee.Entity as Seller);

Now I have a list of the buyers and sellers, with their primary keys assigned, and I can do whatever I want with them. And I also return the result of the save.

foreach (var buyer in buyers)
{
    Console.WriteLine(buyer);
}
foreach (var seller in sellers)
{
    Console.WriteLine(seller);
}

return resultOfSave;

Here is the output that is logged to the console -

Buyer - PK:1, Name:Ruby Hickle, Bank Account Number:KZ890121013PAG885951
Buyer - PK:2, Name:Marvin Pagac, Bank Account Number:GB30QLID00729104800721
Buyer - PK:3, Name:Justin Hermiston, Bank Account Number:ES8575006376316040462024
Seller - PK:1, Name:Leslie Howell, Bank Account Number:QA17AQHP306W952138247Q04B0935
Seller - PK:2, Name:Ricky Rodriguez, Bank Account Number:GE16491266738701837401
Seller - PK:3, Name:Clint Runte, Bank Account Number:LI94080944Q412561Y01Z

Rest of the code

You can find the rest of the code in the attached zip file.

I use Docker to run SQL Server in a container, to see how to do that, check my post here. And to use it with Entity Framework, see this post.

Download full source code.

comments powered by Disqus

Related