نحوهی معرفی DbContext pooling
اینبار بجای روش قبلی و استفاده از متد AddDbContext
services.AddDbContext<BloggingContext>( options => options.UseSqlServer(connectionString));
services.AddDbContextPool<BloggingContext>( options => options.UseSqlServer(connectionString));
محدودیتهای روش DbContext pooling
در حالت استفادهی از روش AddDbContextPool، دیگر متد OnConfiguring کلاس Context سفارشی شما فراخوانی نخواهد شد. بنابراین تمام تنظیمات ابتدایی برنامه را باید به همان کلاس آغازین برنامه منتقل کنید و کلاس Context، این تنظیمات را به صورت ذیل از طریق سازندهی آن دریافت میکند:
public class BloggingContext : DbContext { public BloggingContext(DbContextOptions<BloggingContext> options) : base(options){}
همچنین باید درنظر داشت که استفادهی مجدد از یک Context به معنای حفظ مقادیر فیلدهای private کلاس Context سفارشی شما نیز میشود. در اینجا پس از پایان هر درخواست، تنها وضعیت Context از دیدگاه EF به حالت اول بازگشت داده میشود؛ اما حالت شیء Context و تمام اطلاعات فیلدهای خصوصی آن در همان حالت قبلی (و همان وهلهی موجود پیشین و اصلی) رها میشوند. چون وهله سازی مجددی از آن صورت نخواهد گرفت.
یک مثال: بررسی بهبود کارآیی برنامه در حالت استفادهی از DbContext pooling
کدهای کامل این مثال را برای اجرا میتوانید از اینجا دریافت کنید: ContextPooling.zip
در اینجا یکبار حالت متداول AddDbContext
public static void RunWithoutContextPooling() { Console.WriteLine("\nRun Without ContextPooling"); var serviceProvider = new ServiceCollection() .AddEntityFrameworkSqlServer() .AddDbContext<BloggingContext>( c => c.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Demo.ContextPooling;Trusted_Connection=True;ConnectRetryCount=0;")) .BuildServiceProvider(); new RunTests().Start(serviceProvider); }
public static void RunWithContextPooling() { Console.WriteLine("\nRun With ContextPooling"); var serviceProvider = new ServiceCollection() .AddEntityFrameworkSqlServer() .AddDbContextPool<BloggingContext>( c => c.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Demo.ContextPooling;Trusted_Connection=True;ConnectRetryCount=0;"), poolSize: 16) .BuildServiceProvider(); new RunTests().Start(serviceProvider); }
Run Without ContextPooling [10:49:30.728] Context creations: 637 | Requests per second: 597 [10:49:31.746] Context creations: 1069 | Requests per second: 1050 [10:49:32.765] Context creations: 1088 | Requests per second: 1067 [10:49:33.784] Context creations: 1139 | Requests per second: 1119 [10:49:34.802] Context creations: 1138 | Requests per second: 1117 [10:49:35.831] Context creations: 1153 | Requests per second: 1120 [10:49:36.845] Context creations: 1126 | Requests per second: 1111 [10:49:37.873] Context creations: 1014 | Requests per second: 987 [10:49:38.898] Context creations: 1139 | Requests per second: 1111 [10:49:39.918] Context creations: 1086 | Requests per second: 1065 Total context creations: 10592 Requests per second: 1034 Run With ContextPooling [10:49:40.982] Context creations: 32 | Requests per second: 1388 [10:49:41.991] Context creations: 0 | Requests per second: 1691 [10:49:43.014] Context creations: 0 | Requests per second: 1684 [10:49:44.031] Context creations: 0 | Requests per second: 1702 [10:49:45.049] Context creations: 0 | Requests per second: 1694 [10:49:46.067] Context creations: 0 | Requests per second: 1401 [10:49:47.075] Context creations: 0 | Requests per second: 1510 [10:49:48.107] Context creations: 0 | Requests per second: 1669 [10:49:49.127] Context creations: 0 | Requests per second: 1679 [10:49:50.147] Context creations: 0 | Requests per second: 1688 Total context creations: 32 Requests per second: 1610