(Multiple Active Result Sets (MARS یکی از قابلیتهای SQL SERVER است. این قابلیت در واقع این امکان را برای ما فراهم میکند تا بر روی یک Connection همزمان چندین کوئری را به صورت موازی ارسال کنیم. در این حالت برای هر کوئری یک سشن مجزا در نظر گرفته میشود.
کلاس Context:
ابتدا یک سطر جدید را توسط کد زیر به دیتابیس اضافه میکنیم:
اکنون میخواهیم قیمت محصولاتی را که در دستهبندی Cate1 قرار دارند، تغییر دهیم:
خوب؛ اکنون اگر برنامه را اجرا کنیم با خطای زیر مواجه میشویم:
این استثناء زمانی اتفاق میافتد که بر روی نتایج حاصل از یک کوئری، یک کوئری دیگر را ارسال کنیم. البته استثنای صادر شده بستگی به کوئری دوم شما دارد ولی در حالت کلی و با مشاهده Stack Trace، پیام فوق نمایش داده میشود. همانطور که در کد بالا ملاحظه میکنید درون حلقهی forach ما به پراپرتی Price دسترسی پیدا کردهایم، در حالیکه کوئری اصلی ما هنوز فعال (Active) است. MARS در اینجا به ما کمک میکند که بر روی یک Connection، بیشتر از یک کوئری فعال داشته باشیم. در حالت عادی Entity Framework Code First این ویژگی را به صورت پیشفرض برای ما فعال نمیکند. اما اگر خودمان کانکشناسترینگ را اصلاح کنیم، این ویژگی SQL SERVER فعال میگردد. برای حل این مشکل کافی است به کانکشناسترینگ، MultipleActiveResultSets=true را اضافه کنیم:
لازم به ذکر است که این قابلیت از نسخه SQL SERVER 2005 به بالا در دسترس میباشد. همچنین در هنگام استفاده از این قابلیت میبایستی موارد زیر را در نظر داشته باشید:
مدل:
namespace EnablingMARS.Models { public class Product { public int Id { get; set; } public string Title { get; set; } public string Desc { get; set; } public float Price { get; set; } public Category Category { get; set; } } public enum Category { Cate1, Cate2, Cate3 } }
namespace EnablingMARS.Models { public class ProductDbContext : DbContext { public ProductDbContext() : base("EnablingMARS") {} public DbSet<Product> Products { get; set; } } }
MyContext.Products.Add(new Product() { Title = "title1", Desc = "desc", Price = 4500f, Category = Category.Cate1 }); MyContext.SaveChanges();
foreach (var product in _dvContext.Products.Where(category => category.Category == Category.Cate1)) { product.Price = 50000; MyContext.SaveChanges(); }
There is already an open DataReader associated with this Command which must be closed first.
"Data Source=(LocalDB)\v11.0;Initial Catalog=EnablingMARS; MultipleActiveResultSets=true"
- وقتی کانکشنی در حالت MARS برقرار میشود، یک سشن نیز همراه با یکسری اطلاعات اضافی برای آن ایجاد شده که باعث ایجاد Overhead خواهد شد.
- دستورات مارس thread-safe نیستند.