ورود

View Full Version : ارور فیلد محاسبه شده (محاسباتی) از طریق Navigation property هنگام بایند به Datagrid



mr.sirwan
پنج شنبه 28 مرداد 1395, 13:09 عصر
سلام خدمت دوستان و اساتید محترم
من داخل پروژه م از تکنولوژی EF: Code-First استفاده میکنم داخل models یک کلاس به اسم DupsOfInterLetters دارم که با کلاس User از طریق Navigation property در ارتباطه داخل این کلاس دوتا فیلد محاسباتی ایجاد کردم برای واکشی اسم کامل(نام و نام خانوادگی) User مربوطه به ترتیب زیر:

142035

حالا من داخل فرمم میخوام این کلاس DupsOfInterLetters رو به Datagridview بایند کنم که اطلاعات رو نشون بده(از جمله این دوتا فیلد محاسباتی) من داخل بدنه try-Catch عمل بایند رو انجام میدم و داخل بدنه finally ابجکت DatabaseContext رو Dispose و null میکنم به همین خاطر به ارور میخورم و ارور هم دقیقا مربوط به همین دوتا فیلد محاسباتی هستش. اینم متن ارور:

142036

که خب میدونم چی میگه و منظورش چی هستش، اما من نیاز دارم که ابجکت DatabaseContext رو Dispose کنم، همچنین به این دوتا فیلد هم نیاز شدید دارم، از متد Include داخل کوئری Linq-to-entity هم استفاده میکنم اما بازم ارور میده و تفاوتی ایجاد نمیکنه، اما با حذف کد مربوط به Dispose کردن DatabaseContext دیگه ارور نمیده و اونطوری که انتظار دارم کار میکنه، اینم کد مربوطه:

Models.DatabaseContext oDBC = null;
try
{
oDBC = new Models.DatabaseContext();

List<Models.DupsOfInterLetters> InLetters = new List<Models.DupsOfInterLetters>();
InLetters = oDBC.DupsOfInterLetters
.Include(i => i.Referraller)
.Include(i => i.Referraled)
.Where(d => d.ReferraledToEmployeeCode == frmMain.CurrentUser)
.GroupBy(grouping => grouping.LetterId).ToList()
.Select(g => g.OrderBy(o => o.Id).Last())
.OrderByDescending(l => l.Id)
.Skip((PageIndex - 1) * (PageSize))
.Take(PageSize)
.ToList();

dgvLetters.DataSource = null;
dgvLetters.DataSource = InLetters;

InLetters = null;
}
catch (Exception ex)
{

MessageBox.Show(ex.Message);
}
finally
{
if (oDBC != null)
{
oDBC.Dispose();
oDBC = null;
}
}

اگه راهنمایی کنین خیلی ممنون میشم، نیاز فوری دارم :افسرده::افسرده::افسرده:

mr.sirwan
جمعه 29 مرداد 1395, 20:37 عصر
یعنی تا حالا هیچکس با این مشکل مواجه نشده؟؟؟!!!! چرا تعداد بازدید کننده های این بخش از فروم انقد کمه؟؟؟؟؟ :عصبانی++::عصبانی++: حتما کسی از وجود این بخش خبر نداره:عصبانی++::عصبانی++::عصب نی++:

Mahmoud.Afrad
شنبه 30 مرداد 1395, 10:37 صبح
همیشه سعی کنید متد tolist آخرین متد فراخوانی شده باشه
List<Models.DupsOfInterLetters> InLetters =
oDBC.DupsOfInterLetters
.Where(d => 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)
.Include(i => i.Referraller)
.Include(i => i.Referraled)
.ToList();

mr.sirwan
شنبه 30 مرداد 1395, 11:13 صبح
حرف شما متین، ولی به این خاطر یه Tolist دیگه هم بعد از GroupBy اضافه کردم چون ارور میداد دقیق یادم نیس متن ارور چی بود ولی مضمون کلیش این بود که Linq اینو نمیفهمه و باید از اینترفیس IQueryable ارثبری کنه، کلی تو اینترنت گشتم راه حل های مزخرف و طولانی موجود بود و اینکه اصلا واسه من کارایی نداشتن، منم اتفاقی یه ToList رو به GroupBy اضافه کردم و دیدم مشکل حل شد
درمورد جابجایی متدهای Include هم همه جوره امتحان کردم بازم مشکل حل نشد، راستش من قبلا از یک ابجکت DatabaseContext سراسری داخل فرمم استفاده میکردم و برای هر متد و هر عملی که با دیتابیس در ارتباط هستش از این ابجکت استفاده میکردم و خیلی هم قشنگ جواب میداد، ولی اون روش هم در بعضی مواقع خاص که هنوزم نتونستم بفهمم چه شرایطی واسه این دوتا پراپرتی محاسباتی ارور میداد، البته ارور با مال الان متفاوت بود و میگفت مثلا Referraller object reference not set to an instance of an object به خاطر همین ارور بود که اومدم به ازای هر متد یک ابجکت DatabaseContext درست کردم و فک میکردم مشکلم مرتفع میشه، که نشد... الان باز میرم سراغ روش قبلی مثل اینکه کسی جوابی نداره

به هرحال ممنون بابت نظرتون

Mahmoud.Afrad
شنبه 30 مرداد 1395, 17:48 عصر
متد Last قابل ترجمه به sql نیست به همین دلیل خطا میده و شما مجبور به استفاده از tolist میشید(که البته راه حل درستی نیست) به جاش باید به صورت نزولی مرتب و اولین عنصر رو دریافت کنید.


کدی که بنده گذاشتم رو تست کردید یا نه؟ نتیجه؟



پ.ن:
در طرح سوال ، عکس به تنهایی بدرد نمیخوره و بایست کد کلاس ها رو کامل بزارید تا بتونیم در رفع خطا کمکتون کنیم.

mr.sirwan
شنبه 30 مرداد 1395, 18:26 عصر
اگه اشتباه میکنم خواهشا تصحیح کنین: دلیل اشتباه بودن بیش از یک Tolist اینه که این متد اطلاعات رو به حافظه Ram منتقل میکنه و منابع سیستم رو اشغال میکنه، حالا به همین خاطر اگر بیشتر از یک Tolist استفاده کنیم این حجم از اطلاعات دو برابر و چندبرابر میشه، درسته آیا؟

بله کدتون مثل یه افسون کار میکنه، خیلی ممنون

درمورد کلاس ها هم، من اومدم و خطایابی کردم و اون پراپرتی هایی که ارور میدن رو واستون لیست کردم، گذاشتن کد کلاسهایی که استفاده میکنم فقط باعث گیج شدن خواننده میشه
سپاس فراوان

Mahmoud.Afrad
یک شنبه 31 مرداد 1395, 02:32 صبح
tolist باعث لود داده ها در حافظه میشه و حجم اشغالی بستگی به اطلاعات لود شده داره. در کد اولیه شما، با اولین tolist تمام داده های منطبق بر کوئری قبل از آن یعنی تمام رکوردهایی که شرط Where در آنها صدق میکند، گروهبندی شده و همه به رم منتقل میشن. البته همراه با اطلاعات وابسته Referraller و Referraled . و حتی قبل از اینکه صفحه بندی اعمال بشه(در حالی که یکی از مزایای صفحه بندی لود اطلاعات مورد نیاز هست نه همه رکوردها) و بعد از اون، ادامه کوئری روی لیست اجرا خواهد شد نه دیتابیس.
اما باید تا حد امکان ، کوئری را روی دیتابیس به اجرا در بیارید.