Click here to Skip to main content
15,885,365 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
My question: what determines the speed(performance) of calling DbContext.SaveChanges() method? And is it a bad practice to put all the DbSets in a single DbContext?

I have a c#/WPF/MS SQL Server/Entity Framework Core project, which is actually for my company's wholesale business.

I implemented a single DbContext which contains dozens of DbSet's, each of which, of course, represents a table in the database. There are about 10 major tables representing orders, order details, customers, products, etc, and each of the major DbSet/tables contains about 50,000 to 150,000 records in it. The problem is when DbContext.SaveChanges method is called, it takes over 9,000ms(9 sec) to execute! I put ALL of the DbSets in the same DbContext. Is this a bad habit and the cause for slow speed?

For a test, I created a separate DbContext and put only one DbSet in it. The DbSet has about 100,000 records, but calling SaveChanges for that took about 500ms, which was a significant improvement.

Given my situation, what is the best practice for database performances? Please help.

What I have tried:

public class MyDbContext : DbContext
{
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseLazyLoadingProxies().UseSqlServer(DbConn.GetConnStr());
            base.OnConfiguring(optionsBuilder);
        }

        public DbSet<Order> Orders { get; set; }     // This has 100k+ records.
        public DbSet<OrderDetail> OrderDetails { get; set; }     // This has 150k+ records.
        public DbSet<Ship> Ships { get; set; }               // 100k+ records
        public DbSet<ShipDetail> ShipDetails { get; set; }   // 150k+ records
        public DbSet<Customer> Customers { get; set; }     // 100k records
        public DbSet<Product> Products { get; set; }       // 10k+ records
        public DbSet<ProductStock> ProductStocks { get; set; }
        public DbSet<ProductPrice> ProductPrices { get; set; }
        public DbSet<PriceType> PriceTypes { get; set; }
        public DbSet<Claim> Claims { get; set; }
        public DbSet<Carrier> Carriers { get; set; }
        public DbSet<Channel> Channels { get; set; }
        public DbSet<Import> Imports { get; set; }
        public DbSet<ImportDetail> ImportDetails { get; set; }
}
Posted
Updated 11-Sep-21 11:22am
v2
Comments
[no name] 6-Sep-21 3:53am    
Only the changed entities get written. And if you're reading in the process of updating, that counts too. Then there's the question of stored procs.

One of our applications uses EF Core with a single DbContext containing 116 tables, and it doesn't take anywhere near that long to save the changes, even with a full audit log of all changes running every time.

It's hard to say what the problem is without seeing the relevant parts of your code. But at a guess, you're either loading too much data, or you're using a single instance of the context across multiple unrelated operations.
 
Share this answer
 
Thank you, Gerry Schmitz and Richard Deeming for your replies. I found a solution to my question. As both of you mentioned, the problem was not the fact that a single DbContext has all tables in it. The problem was that I was using and passing around a single "instance" of my DbContext across multiple operations throughout the lifetime of running the appplication. This should NEVER be done with a DbContext.

I figured that a DbContext is supposed to be instantiated for a single unit-of-work or a single operation and then dispose the instance as soon as the operation is over. I was reading ALL of the DataSets into the DbContext and querying as much as possible with the single DbContext instance. This is a guarantee for slow performance.

I said it took 9 seconds(9,000ms) to persist changes to the DB by calling SaveChanges. Now it takes 250ms(0.25 sec) to get the same job done. Hope my comment helps for anyone with the same issue.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900