Entity Framework ChangeTracker Stream and Save to Query Afterwards

那年仲夏 提交于 2019-12-02 09:37:19

@DerrikRodgers, time required to check if Entity is an instance of a certain type is not comparable to a transaction time. 500 transactions/second will work absolutely fine having code you provided.

public void ReportChanges()
{
  var entities=ChangeTracker
           .Entries()
           .Where(x => x.Entity is Product)
           .Where(x => x.State == EntityState.Modified || x.State == EntityState.Deleted || x.State == EntityState.Added)
           .GroupBy(x=>x.State, x => x.Entity as Product)
           .ToList();
  ... // Producer/Consumer to do not block current thread and control concurrency
}

Get performance baseline with a synthetic test, something like this:

var cc = new ApplicationDbContext();
for (int i = 0; i < 100; i++)
    cc.Users.Add(new ApplicationUser() { Id = i });

var sw = Stopwatch.StartNew();
for (int i = 0; i < 1000; i++)
    cc.ReportChanges();
sw.Stop();
Console.WriteLine($"1000 times to report 100 entities took {sw.ElapsedMilliseconds}ms. Rate {1000*100/(sw.ElapsedMilliseconds/1000.0)} items/s");
Console.ReadKey();

// 1000 times to report 100 entities took 461ms. Rate 216919.739696312 items/s

Another question is what you are going to do with the filtered entities. That thing might be slow. For example if you'll try to log them all and you don't use asynchronous sinks/targets in your logger, this will be slow. In this case you can implement Producer/Consumer pattern and pipe filtered entities to another consumer which will dispatch them in a different thread and do something long. Rx.NET might be very helpful in this case.

Instead of producer/consumer you can just start a Task, but that might lead to thread pool starvation and I'd recommend explicitly control parallelism of your 'slow' operations.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!