نمایش نتایج 1 تا 15 از 15

نام تاپیک: ادغام دو کوئری در EF (کوئری اول شرط قبل از گروهبندی-کوئری دوم شرط بعد از گروهبندی)

  1. #1

    ادغام دو کوئری در EF (کوئری اول شرط قبل از گروهبندی-کوئری دوم شرط بعد از گروهبندی)

    سلام و خسته نباشید، ابتدا از مدیران عزیز عذر خواهی میکنم که این تاپیک زیاد با این تالار مرتبط نیس، ولی مجبور شدم چون دیدم تالار EF زیاد بازدید کننده نداره و قبلا واسه یه تاپیک دیگه به جواب نرسیدم
    دوستان من یه همچین جدولی دارم:


    و میخوام دو کوئری Select زیر رو که با EF: Code-First نوشته شدن به صورت همزمان اجرا کنم و جمعا به تعداد PageSize از هر دو کوئری برام رکورد واکشی بشه:
    List<Models.DupOfInLetters> InDups = new List<Models.DupOfInLetters>();
    InDups = oDBC.DupOfInLetters
    .Where(d => d.InReferraled.IsReadyToGo == true
    && d.InReferraled.IsEndOfWorK == false
    && d.InReferraled.IsArchived == false
    && d.InReferraled.IsSigned == true
    && (d.SendType == Models.EnumTypes.DuplicationTypes.رونوشت)
    && d.ReferraledToEmployeeCode == frmMain.CurrentUser)
    .GroupBy(grouping => grouping.LetterId)
    .Select(g => g.OrderByDescending(o => o.Id).FirstOrDefault())
    .OrderByDescending(l => l.Id)
    .Skip((PageIndex - 1) * (PageSize))
    .Take(PageSize)
    .ToList();


    List<Models.DupOfInLetters> InDups = new List<Models.DupOfInLetters>();
    InDups = oDBC.DupOfInLetters
    .Where(d => d.InReferraled.IsReadyToGo == true
    && d.InReferraled.IsEndOfWorK == false
    && d.InReferraled.IsArchived == false
    && d.InReferraled.IsSigned == true
    && (d.SendType == Models.EnumTypes.DuplicationTypes.ارجاع))
    .GroupBy(grouping => grouping.LetterId)
    .Select(g => g.OrderByDescending(o => o.Id).FirstOrDefault())
    .Where(d => d.ReferraledToEmployeeCode == frmMain.CurrentUser)
    .OrderByDescending(l => l.Id)
    .Skip((PageIndex - 1) * (PageSize))
    .Take(PageSize)
    .ToList();


    دو قطعه کد بالا در دو خط با هم تفاوت دارند، قطعه کد پایینی یکی از شرطاش که با بالایی فرق داره (d.SendType == Models.EnumTypes.DuplicationTypes.ارجاع) و دیگه اینکه شرط d.ReferraledToEmployeeCode == frmMain.CurrentUser در قطعه کد دوم بعد از متد Select قرار گرفته
    آیا راهی هست که این دو رو باهم ترکیب کنم که همزمان اجرا بشن و درصورت تکراری بودن رکورد های واکشی شده از این دو قطعه کد، فقط یک رکورد انتخاب بشه، اون هم از نوع ارجاع؟؟ اگه توو EF امکان پذیر نیست، با دستورات SQL چطوری همچین کوئری رو بنویسم؟
    سپاس از راهنمایتون
    آخرین ویرایش به وسیله mr.sirwan : جمعه 23 مهر 1395 در 01:19 صبح

  2. #2

    نقل قول: اجرای همزمان دو کوئری در EF

    در کوئری دوم ، شرط خط 26 رو میتونید به قبل از گروهبندی منتقل کنید. در اینصورت دو کوئری شبیه هستند و میتونید به یک کوئری تبدیل کنید.

  3. #3

    نقل قول: اجرای همزمان دو کوئری در EF

    نقل قول نوشته شده توسط Mahmoud.Afrad مشاهده تاپیک
    در کوئری دوم ، شرط خط 26 رو میتونید به قبل از گروهبندی منتقل کنید. در اینصورت دو کوئری شبیه هستند و میتونید به یک کوئری تبدیل کنید.
    ممنون از پاسخگوییتون، هدف هرکدوم از این دو کوئری متفاوته، در ادامه توضیح میدم:

    کوئری اول:

    ابتدا پس از بررسی چهار فیلد بولین، میاد تمامی رکوردهایی که از نوع رونوشت هستند و گیرنده شون کاربر جاری هستش رو میگیره، در متد GroupBy بر اساس آیدی نامه گروه بندی میکنه، حالا بر اساس آیدی همین رکورد ها بصورت نزولی مرتب میکنه و اولین روکورد رو Select میکنه (ممکنه یک نامه توسط چندین شخص به کاربر جاری رونوشت شده باشه، واسه همین این اعمال انجام میشه)

    اینم یه نمونه از اطلاعات داخل جدول (فقط رکوردهای نوع رونوشت رو اینجا نوشتم) رنگهای قرمز اونهایی هستن که توسط کوئری اول برای گیرنده ای با کد 6 انتخاب میشن



    اما کوئری دوم:

    پس از بررسی چهار فیلد بولین، میاد تمامی رکوردهایی که از نوع ارجاع هستند رو برمیگردونه، در متد GroupBy بر اساس آیدی نامه گروه بندی میکنه، حالا بر اساس آیدی همین رکورد ها بصورت نزولی مرتب میکنه و اولین روکورد رو Select میکنه، حالا میاد داخل where چک میکنه که این رکوردی که انتخاب شده آیا ارجاع گیرنده ش کاربر جاری هستش یا خیر، تمامی رکوردهایی که اخرین ارجاعشون مربوط به کاربر جاری هست رو برمیگردونه (به این خاطر که سیاست من در بحث ارجاعات به این صورت هست که هر نامه در هر زمان، به عنوان ارجاع فقط در دست یک نفر باشه اونم آخرین ارجاعیه که صورت گرفته)

    اینم یه نمونه از اطلاعات داخل جدول (فقط رکوردهای نوع ارجاع رو اینجا نوشتم) رنگهای قرمز اونهایی هستن که توسط کوئری دوم برای ارجاع گیرنده ای با کد 9 انتخاب میشن
    آخرین ویرایش به وسیله mr.sirwan : جمعه 23 مهر 1395 در 02:13 صبح

  4. #4

    نقل قول: اجرای همزمان دو کوئری در EF

    کوئری اول که بحثی نیست.
    در کوئری دوم ، فرقی نمیکنه اول گروهبندی و بعد شرط اعمال بشه یا اول شرط و بعد گروهبندی و سلکت بزرگترین آیدی. مثلا برای همان کد گیرنده 9، چه اینکه اول گروهبندی و بعد کد گیرنده 9 رو سلکت کنید و چه اول رکوردهای با گیرنده 9 رو سلکت و بعد گروهبندی ... نتیجه یکسان هست.

  5. #5

    نقل قول: اجرای همزمان دو کوئری در EF

    کوئری دوم به این شکلی که کدش رو گذاشتم اونطوری که انتظار دارم برام رکوردارو واکشی میکنه،
    چیزی که من انتظار دارم:
    اگر نامه ای قبلا به من ارجاع شده باشه و من نامه رو به یه نفر دیگه ارجاع بدم، دیگه در دفعات بعدی نامه ارجاعی در دست من نیست و در دست آخرین ارجاع گیرنده خواهد بود (با اینکه من جزوی از ارجاع گیرنده های این نامه بودم ولی دیگه نباید واسه من نشون داده بشه چون من یا هر کس دیگه ای این نامه رو به شخص دیگه ای ارجاع داده، بطور خلاصه من روش سلسله مراتبی رو پیش گرفتم در هر زمان یک نامه از نوع ارجاع فقط در دست یک نفر باشه)

    یک رکورد جدید به مثال پست قبلی اضافه میکنم و بررسی میکنیم که کوئری اصلی چه رکوردهایی رو برمیگردونه و با تغییر در کوئری چه رکوردهایی واکشی میشن
    الان در این جدول، رکوردهایی که باید برای گیرنده ای با کد 9 واکشی بشن فقط رکود قرمز رنگ هستش که این امر توسط کوئری اصلی درست اجرا میشه، اما با تغییر کوئری به این شکل که شما فرمودین:


    InDups = oDBC.DupOfInLetters
    .Where(d => d.InReferraled.IsReadyToGo == true
    && d.InReferraled.IsEndOfWorK == false
    && d.InReferraled.IsArchived == false
    && d.InReferraled.IsSigned == true
    && (d.SendType == Models.EnumTypes.DuplicationTypes.ارجاع)

    && d.ReferraledToEmployeeCode == frmMain.CurrentUser)
    .GroupBy(grouping => grouping.LetterId)
    .Select(g => g.OrderByDescending(o => o.Id).FirstOrDefault())
    .OrderByDescending(l => l.Id)
    .Skip((PageIndex - 1) * (PageSize))
    .Take(PageSize)
    .ToList();



    هم رکورد قرمز رنگ و هم رکورد نارنجی رنگ واکشی میشن، که من همچین چیزی رو نمیخوام

    امیدوارم منظورمو رسونده باشم، خیلی ممنون از پاسخگوییتون جناب آفراد
    آخرین ویرایش به وسیله mr.sirwan : جمعه 23 مهر 1395 در 12:47 عصر

  6. #6

    نقل قول: اجرای همزمان دو کوئری در EF

    نقل قول نوشته شده توسط mr.sirwan مشاهده تاپیک
    ...
    الان در این جدول، رکوردهایی که باید برای گیرنده ای با کد 9 واکشی بشن فقط رکود قرمز رنگ هستش
    الان سوالی که برام پیش اومده مگر براساس letterid گروهبندی نمیشه، پس خط رنگ نارنجی هم باید سلکت بشه چون این دو رکورد در یک گروه و مربوط به یک نامه نیستتند.(letterId یکسانی ندارند.)

  7. #7

    نقل قول: اجرای همزمان دو کوئری در EF

    نقل قول نوشته شده توسط Mahmoud.Afrad مشاهده تاپیک
    الان سوالی که برام پیش اومده مگر براساس letterid گروهبندی نمیشه، پس خط رنگ نارنجی هم باید سلکت بشه چون این دو رکورد در یک گروه و مربوط به یک نامه نیستتند.(letterId یکسانی ندارند.)
    خیر، اجازه بدین مرحله به مرحله اجرای کوئری رو بررسی کنیم (کاری به فیلد های بولین نداریم):

    ابتدا در اولین Where تمامی رکوردهایی که از نوع ارجاع هستند انتخاب میشن به این شکل:
    حالا میرسیم به GroupBy و OrderByDescending
    حالا میرسیم به Select.FirstOrDefault در این حال میاد اولین رکورد از هر گروه رو select میکنه که این رکوردها انتخاب میشن:
    حالا میرسیم به Where دوم، اینجا میاد و به ازای هر سه رکورد انتخاب شده شرط RefferraledTo==9 رو چک میکنه، که فقط در یک رکورد این شرط صدق میکنه:

    اگر اشتباه میکنم ممنون میشم بفرمایید

  8. #8

    نقل قول: اجرای همزمان دو کوئری در EF

    خب ، میشه طور دیگری هم بیان کرد، برای نامه های نوع "ارجاع" ، به شرطی باید سلکت از گروه صورت بگیره که اون نامه برای شخص دیگری ارسال نشده باشه. یعنی گروهی که Refferraller برابر 9 داره باید کنار گذاشته بشه(یا اینکه گروهی انتخاب بشه که همه رکوردهاش refferraller مخالف 9 دارند).

    کلا شرطها رو منتقل کنید بعد از GroupBy. در اینصورت دو کوئری رو میتونید ترکیب کنید
                var result =
    db.DupOfInLetters
    .GroupBy(g => g.LetterId)
    .Select(g =>
    g.OrderByDescending(rec => rec.Id)
    .FirstOrDefault(d =>
    (d.SendType == Models.EnumTypes.DuplicationTypes.ارجاع
    && g.All(record => record.Refferraller != currentUser)
    && d.RefferralledTo == currentUser)
    || (d.SendType == Models.EnumTypes.DuplicationTypes.رونوشت && d.RefferralledTo == currentUser)))
    .OrderByDescending(l => l.Id)
    .Skip((PageIndex - 1) * (PageSize))
    .Take(PageSize)
    .ToList();

  9. #9

    نقل قول: اجرای همزمان دو کوئری در EF

    بسیار سپاسگذار از راهنماییتون، کد رو امتحان کردم، شرط Where که فیلد های بولین رو چک میکرد رو قبل از groupby قرار دادم و برنامه رو اجرا کردم، ارور object reference not set to an instance of an object داد، trace کردم دیدم سه تا رکورد برگردونده، که اخرین رکورد یعنی سومین رکورد NULL هستش، دو رکورد اول درستن، میدونم که علتش متد FirstOrDefault هستش اما درک نمیکنم چرا Null برگردونده؟؟

    -----------------------------------------------------------------

    ویرایش:
    بنده قسمت g.All(record => record.Refferraller != currentUser) رو حذف کردم و درست شد، چون با این خط رکوردای درست رو نشون نمیداد ولی الان با حذفش از کوئری دیگه مشکل برطرف شد.

    جناب آفراد یه دنیا ممنون
    آخرین ویرایش به وسیله mr.sirwan : جمعه 23 مهر 1395 در 23:42 عصر

  10. #10

    نقل قول: ادغام دو کوئری در EF

    g.All(record => record.Refferraller != currentUser) رو نباید حذف کنید. این شرط میاد رکورد با رنگ نارنجی رو حذف میکنه


    ببینید چی null هست که خطا میده.

  11. #11

    نقل قول: ادغام دو کوئری در EF

    نقل قول نوشته شده توسط Mahmoud.Afrad مشاهده تاپیک
    g.All(record => record.Refferraller != currentUser) رو نباید حذف کنید. این شرط میاد رکورد با رنگ نارنجی رو حذف میکنه


    ببینید چی null هست که خطا میده.
    حق با شماس، ولی در نظر بگیرین که یک نامه در دست دو یا چند نفر بصورت چرخشی هی ارجاع بشه، مثلا نامه 17 رو کاربر 5 به 9 ارجاع میده، کاربر 9 به 7 ارجاع میده و حالا دوباره کاربر 7 به 9 ارجاع میده، الان دقیقا همچین وضعیتی تو داده های جدولم وجود داره، که میشه آخرین ارجاع نامه 17 و ارجاع گیرنده 9 که باید برای کاربر 9 نشون داده بشه ولی با اون خط کد میاد کلا ارجاعات مربوط به نامه 17 رو نادیده میگیره، همین نامه ای که ذکر کردم واکشی شد

    بازم ممنون


    ویرایش:
    ولی یه چیز عجیب اینکه شد همون کوئری که قبلا استفاده میکردم، مثل همونی که شما تو پست دوم گفتین فقط شرظ "ارجاع" و "رونوشت" رو باهم Or کن، قبلا همینکارو میکردم ولی درست کار نمیکرد پس این کوئری جدید هم اشتباه واکشی میکنه
    جریان چیه؟؟ ای بابا
    آخرین ویرایش به وسیله mr.sirwan : شنبه 24 مهر 1395 در 00:41 صبح

  12. #12

    نقل قول: ادغام دو کوئری در EF

    خب من هم گفتم نباید شرط رو حذف کنید.

    کوئری زیر رو امتحان کنید
                var result = 
    (
    from d in db.DupOfInLetters
    group d by new {d.LetterId, d.SendType}
    into grouping
    let referentialLetter = grouping.Where(rec => rec.SendType == 0).OrderByDescending(rec => rec.Id).FirstOrDefault()
    let replicationLetter = grouping.Where(rec => rec.SendType == 1).OrderByDescending(rec => rec.Id).FirstOrDefault(rec => rec.SendType == 1 && rec.RefferralledTo == currentUser)
    let isReferential = grouping.Key.SendType == 0 && referentialLetter != null && referentialLetter.RefferralledTo == currentUser
    select isReferential ? referentialLetter : replicationLetter
    )
    .Where(rec => rec != null).ToList();

    اگر جواب نداد ، تنها راهی که به نظرم میرسه اینه که دو کوئری رو با هم union کنید.
    آخرین ویرایش به وسیله Mahmoud.Afrad : شنبه 24 مهر 1395 در 23:01 عصر

  13. #13

    نقل قول: ادغام دو کوئری در EF

    با تشکر، این درست جواب میده، ولی فرض کنین یه نامه قبلا به من رونوشت شده و بعدها به بنده ارجاع هم میشه، این کدی که شما گذاشتین جفتشون رو برمیگردونه، کجای کد رو تغییر بدم تا این رو هم برطرف کنم؟ یعنی ارجاع رو برگردونه، اولویت ارجاع بیشتر از رونوشت هستش، مگر اینکه من هم نامه رو به شخص دیگه ای ارجاع بدم در اینصورت باید رونوشت واکشی بشه

    یه سوال دیگه آیا میشه همین کد رو کلا به لامبدا اکسپرشن نوشت؟

    خیلی ممنون بابت زحمتی که میکشین جناب آفراد
    آخرین ویرایش به وسیله Mahmoud.Afrad : شنبه 24 مهر 1395 در 23:01 عصر

  14. #14

    نقل قول: ادغام دو کوئری در EF

    خب براساس شماره نامه و کد شخص گیرنده مجددا گروهبندی کنید و اگر تعداد بیش از یک بود نوع ارجاعی و در غیراینصورت همان یک مورد را سلکت کنید.
                var result =
    (
    from d in db.DupOfInLetters
    group d by new {d.LetterId, d.SendType}
    into grouping
    select
    grouping.Key.SendType == 0
    ? grouping.Where(rec => rec.SendType == 0)
    .OrderByDescending(rec => rec.Id)
    .Take(1)
    .FirstOrDefault(d => d.RefferralledTo == currentUser)
    : grouping.Where(rec => rec.SendType == 1)
    .OrderByDescending(rec => rec.Id)
    .FirstOrDefault(rec => rec.SendType == 1 && rec.RefferralledTo == currentUser)
    )
    .Where(rec => rec != null)
    .GroupBy(g => new {g.LetterId, g.RefferralledTo})
    .Select(g =>
    g.Count() > 1
    ? g.FirstOrDefault(rec => rec.SendType == 0)
    : g.FirstOrDefault()
    )
    .ToList();

    این هم معادل لامبدا
                var result =
    db.DupOfInLetters.GroupBy(d => new {d.LetterId, d.SendType})
    .Select(grouping => grouping.Key.SendType == 0
    ? grouping.Where(rec => rec.SendType == 0)
    .OrderByDescending(rec => rec.Id)
    .Take(1)
    .FirstOrDefault(d => d.RefferralledTo == currentUser)
    : grouping.Where(rec => rec.SendType == 1)
    .OrderByDescending(rec => rec.Id)
    .FirstOrDefault(rec => rec.SendType == 1 && rec.RefferralledTo == currentUser))
    .Where(rec => rec != null)
    .GroupBy(g => new {g.LetterId, g.RefferralledTo})
    .Select(g =>
    g.Count() > 1
    ? g.FirstOrDefault(rec => rec.SendType == 0)
    : g.FirstOrDefault()
    )
    .ToList();
    آخرین ویرایش به وسیله Mahmoud.Afrad : شنبه 24 مهر 1395 در 23:39 عصر

  15. #15

    نقل قول: ادغام دو کوئری در EF

    آقای آفراد یک دنیا ممنونات فراوان کار میکنه مشکل ارجاع و رونوشت تکراری هم حل شد، بابت زحماتتون سپاسگذارم

تاپیک های مشابه

  1. سوال: ادغام دو کوئری.؟
    نوشته شده توسط saeed28541 در بخش Access
    پاسخ: 4
    آخرین پست: دوشنبه 13 مهر 1394, 15:59 عصر
  2. ادغام دو پایگاه داده در sql چگونه است
    نوشته شده توسط tahamoqaddam در بخش مدیریت دیتابیس (Database Administration)
    پاسخ: 1
    آخرین پست: دوشنبه 28 اردیبهشت 1394, 08:10 صبح
  3. ادغام دو فایل MDB در C++‎
    نوشته شده توسط avr1320 در بخش برنامه نویسی با زبان C و ++C
    پاسخ: 11
    آخرین پست: شنبه 02 اردیبهشت 1391, 11:44 صبح
  4. ادغام دو مقدار (فیلد) در یک ستون DBGRID
    نوشته شده توسط behnam_dr در بخش مباحث عمومی دلفی و پاسکال
    پاسخ: 2
    آخرین پست: سه شنبه 11 خرداد 1389, 23:57 عصر
  5. ادغام دو فایل exe در یک فایل
    نوشته شده توسط AmirEngineer در بخش مباحث عمومی دلفی و پاسکال
    پاسخ: 4
    آخرین پست: سه شنبه 06 آذر 1386, 22:09 عصر

برچسب های این تاپیک

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •