عنوان:

‫Bulk delete و Bulk update در Entity framework


نویسنده: وحید نصیری
تاریخ: ۱۳۹۱/۱۰/۲۰ ۹:۱۸
آدرس: www.dntips.ir
در Entity framework به کمک امکانات LINQ، نمی‌توان چندین رکورد را با هم (یکجا) حذف کرد یا به روز رسانی نمود. برای مثال دستوراتی مانند Delete from tbl1 where id>3 و یا update tbl1 set f1=2 where id>3 معادلی در LINQ to EF ندارند. برای انجام اینگونه امور یا باید رویه ذخیره شده نوشت و سپس آن‌را در EF فراخوانی کرد؛ یا دستورات SQL خام را مستقیما بر روی بانک اطلاعاتی اجرا کرد و یا باید حلقه‌ای را تشکیل داد و موارد موجود را یک به یک ویرایش یا حذف نمود. مورد آخر خصوصا از لحاظ کارآیی به هیچ عنوان پذیرفتنی نیست.
البته اکثر ORMهای موجود از Bulk operations پشتیبانی نمی‌کنند و این مورد منحصر به EF نیست. علت آن هم به مشکل بودن هماهنگ سازی Context و بانک اطلاعاتی، پس از Bulk operations بر می‌گردد. برای مثال در یک کوئری حذف پیچیده، هماهنگ سازی سطح اول کش یا Tracking API با رکوردهای باقی مانده در بانک اطلاعاتی کار ساده‌ای نیست و اگر اینکار به نحو صحیحی صورت نگیرد، کاربران در حین ذخیره سازی اطلاعات ممکن است با خطاهای همزمانی متوقف شوند (چون هنوز رکوردهای حذف شده در سطح اول کش یا Context وجود دارند، ORM تصور می‌کند کاربر دیگری اطلاعات را حذف کرده است و یک استثنای همزمانی را صادر خواهد کرد).


معرفی Entity Framework Extended Library

کتابخانه «Entity Framework Extended Library» تعدادی متد الحاقی را به EF جهت اعمال Bulk delete و Bulk update سازگار با کوئری‌های تهیه شده به وسیله امکانات LINQ to EF، اضافه می‌کند. البته این کتابخانه امکانات دیگری مانند Future Queries (یکی کردن چند کوئری متفاوت LINQ جهت اجرا در یک رفت و برگشت به بانک اطلاعاتی)، Query Result Cache (سطح دوم کش) را نیز به همراه دارد.


مشاهده مطلب اصلی

نظرات

  • ایمان دارابی در ۱۳۹۱/۱۰/۲۰ ۱۰:۲۸
    در وب معمولا چون چرخه حیات per execution ،context  هستش معمولا مشکلی پیش نمی‌یاد و نیازی به هندل کردن tracking نیست چون در درخواست بعدی تغییرات اصلاح می‌شه.
  • مهمان در ۱۳۹۱/۱۰/۲۰ ۱۰:۵۰
    سلام
    -فرق سطح دوم کش موجود تو این Library با سطح دوم کش معرفی شده در سایت چیه؟
    -کدوم یکی بهتره؟
    • وحید نصیری در ۱۳۹۱/۱۰/۲۰ ۱۱:۱
      امتحان نکردم. بیشتر مورد اولش یعنی bulk/batch update/delete برای من جالب بود.
      • مهمان در ۱۳۹۱/۱۰/۲۰ ۱۱:۱۵
        ممنون،
        در صورتیکه که امتحان کردید،اطلاع رسانی کنید،میخوام نظر شما رو هم بدونم.
  • مهران موسوی در ۱۳۹۱/۱۰/۲۰ ۱۸:۱۸
    بسیار عالی . اقای نصیری این کتابخانه رو تست کردین ؟ در زمینه‌ی bulk/batch update/delete  خوب جوابگو هست ؟ مشکل پیش نمیاره و تداخل نداره با امکانات دیگه‌ی این ORM ؟ کلا قابل اعتماد هست ازش توی پروژه‌های بزرگ استفاده بشه ؟
    • وحید نصیری در ۱۳۹۱/۱۰/۲۰ ۱۹:۵۲
      همیشه در حین کار با ORMها باید مورد بررسی خروجی SQL نهایی تولیدی لحاظ شود. کاری که کتابخانه فوق انجام می‌ده، تولید یک کوئری Delete یا یک کوئری Update به ازای استفاده از متدهای الحاقی جدید Delete و Update ایی است که تهیه کرده.
      • مهمان در ۱۳۹۱/۱۰/۲۰ ۲۳:۱
        ممنون . Batch Update and Delete  و Future Queries این افزونه رو تست کردم تا اونجایی که من بررسی کردم و خروجی‌ها رو با SQL Profiler کنترل کردم خروجی‌های خوبی میده و جالبه که خیلی خوب با LINQ To EF سازگاره ... ممنون از معرفیش
  • م کریمی در ۱۳۹۳/۰۲/۰۷ ۱۲:۱۰
    ایا میشه همچین بروز رسانی هایی هم انجام داد ؟
    Update t1 set t1.f1 = t2.f3 from Table1 t1 join Table2 t2 on t1.f2=t2.f4

    • وحید نصیری در ۱۳۹۳/۰۲/۰۷ ۱۲:۴۷
      ارجاع به ستون‌های دیگر را دو سالی هست که اضافه کرده‌اند. سایر درخواست‌ها را هم در issue tracker آن‌ها ارسال کنید.
  • علی اکبری فرشیــد در ۱۳۹۳/۰۵/۲۵ ۱۰:۵۱
    سلام

    اشکال در استفاده از EntityFramework.Extended

    کد زیر جهت بروز رسانی جدول مرتبط براساس رکوردهای جابجا شده در گرید توسط کاربر می‌باشد:

            public bool RecordMoveUpDown(int idPost1, int rowNumber1, int idPost2, int rowNumber2)
            {
                var result = true;
    
                try
                {
                    _posts.Update(t => t.Id == idPost1, t => new TPersonalPost { Row = rowNumber2 });
                    _posts.Update(t => t.Id == idPost2, t => new TPersonalPost { Row = rowNumber1 });
                }
                catch
                {
                    result = false;
                }
                return result;
            }

    تا حالا هیچ مشکلی نداشتم و دستورات مشابه کاملاً انجام میشد، ولی در حال حاضر ((تنها درحالت اجرا، اولین Update خطای زیر مشاهده شده و از ادامه کار جلوگیری میشود :

    Object reference not set to an instance of an object .

    حتی برای کلاس TPersonalPost یک ctor هم ایجاد کردم ولی تاثیری نداشت.


    • وحید نصیری در ۱۳۹۳/۰۵/۲۵ ۱۱:۷
      بهتر است این نوع خطاها و باگ‌ها را در همان سایت اصلی آن در قسمت issue tracker پروژه پیگیری کنید.
      همچنین این پیگیری باید قابلیت تولید مجدد را داشته باشد. صرفا ذکر چند سطر کد که شبیه به مثال‌های پروژه است و عنوان یک سطر خطای عمومی کافی نیست. نیاز به ارسال stack trace کامل خطا است به علاوه یک مثال ساده‌ی قابل اجرا که بتواند این خطا را سریعا تولید کند تا مدیر پروژه بتواند آن‌را برطرف نماید. در غیراینصورت از خطای گزارش شده‌ی شما صرفنظر می‌شود.
      • علی اکبری فرشیــد در ۱۳۹۳/۰۵/۲۵ ۱۳:۱۷
        ممنون از راهنمای شما. بعد از مراجعه به آدرسی که داده بودید متوجه شدم برای سایرین هم این مشکل بوجود اومده و گزارش شده بود، بنابراین کاملا از روی پروژه‌ها و هارد دیسک حذفش کردم و مجدداً اقدام به دیافت آخرین نسخه کردم.
        نسخه قبلی که گرفته بودم EntityFramework.Extended.6.0.0.86  بود ونسخه فعلی که کلیه مشکلات در اون مرتفع شده EntityFramework.Extended.6.1.0.95 هستش که نرم افزار بدون هیچ مشکلی راه اندازی شد.