PDA

View Full Version : حرفه ای: دقیقا چه موقع ORM ها دستورات sql رو برای اجرا به دیتابیس می فرستند؟



Rejnev
سه شنبه 20 اردیبهشت 1390, 21:42 عصر
با سلام...
اگه دستورات زیر رو در نظر بگیرید برای من سواله که چه هنگام دستور sql مربوطه ساخته میشه.
اگه جواب سوال رو بدونم میتونم برنامه هایی بنویسم که اطلاعات اضافی رو از دیتابیس نخونند تا مجبور نشیم بعدا اونها رو فیلتر کنیم.
به عنوان مثال میخوام ستون "نام" افراد با نامهای ali رو از دیتابیس بیرون بیارم:

var q=DB.PersonsTable;
var q2=q.Where(a=>a.Name.Equals("Ali")).Select(a=>a.Name);
datagrid.DataSource=q2;
// or
var q=DB.PersonsTable.Where(a=>a.Name.Equals("Ali")).Select(a=>a.Name);
datagrid.DataSource=q;

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

mpmsoft
سه شنبه 20 اردیبهشت 1390, 22:44 عصر
زمانی که شما عملیات DataBind انجام می دید و یا درخواستی از بانک دارید برای مثال Count

برای مشاهده دقیق زمان اجرا دستورات از SQL Profiler استفاده کنید و کدتونو قدم به قدم ببرید جلو و زمان اجرا و همچنین کوئیری اجرا رو ببینید

محمدامین شریفی
چهارشنبه 21 اردیبهشت 1390, 16:15 عصر
سلام.
من از entity برای برقراری ارتباط با DB استفاده میکنم و در هنگام کار مشاهده می کنم، که هنگامی که برای اولین بار EM می خواهد با پایگاه داده ارتباط برقرار کند، زمانی را صرف لود اطلاعات میکند.
استنتاج من این است، که آن زمان صَرف گرفتن شمای کلی پایگاه داده می شود، نه لود کردن همه اطلاعات.
درباره select که مثال زدید من از این شیوه استفاده میکنم:


Entities1 _Entities1 = new Entities1();
var _record= _Entities1.Table1.ToList();

و بعد رکورد را به کنترل های مربوطه بایند میکنم.
دستورات شرطی هم قبل از tolist نوشته می شود.

اما دو مثالی که شما زدید، نظر شخصی من این است که هیچ تفاوتی نمی کند و این datagrid است که وظیفه execute را برعهده میگیرد.

[این مطالب نظر شخصی من بر پایه تجربیات بود و شاید خلاف آن باشد]

Rejnev
چهارشنبه 21 اردیبهشت 1390, 18:31 عصر
هنوزم درست نفهمیدم...
من از بایندینگ استفاده نمیکنم.
آیا متد ToList یا ToArray و ... یا مثلا مرور رکورد ها با حلقه ها باعث میشه که قبلش کوئری ساخته بشه؟
فکر میکنم از اونجایی که extension متد های لینک همگی ienum و iquery بر میگردونن، تا زمانی که از این دیتاهای Ienumrable مون استفاده نکنیم، دیتایی خونده نمیشه:

var q=db.TestTable.AsIEnumrable();
q=q.Where(a=>a.id<100);
q=q.Take(10);
dg.DataSource=q.ToList(); // it couses reading from db
foreach(person item in q)
{
//q dobare khoonde mishe, faghat baraye yek bar,
//va na be ezaye har halghe yek bar
}


به نظر من چون تا زمان استفاده نکردن از اطلاعات دیتایی خونده نشده، به ازای دستورات بالا، کوئری ای شبیه زیر ساخته میشه که شرط و top در اون وجود داره.

select top 10 id, name ,... from testTable
where id<100

محمدامین شریفی
شنبه 24 اردیبهشت 1390, 15:03 عصر
سلام.

منظور من از "دستورات شرطی هم قبل از tolist نوشته می شود."، این است که به فرض قبل از tolist می نویسم .where(year<2000).tolist()
بنظر من، صرف ساختن query و یا نوشتن tolist و یا ienum و غیره، همه داده ها از دیتابیس fetch نمی شوند و تنها زمانی داده ها خوانده می شوند که دستوری شبیه به این اجرا شود:



foreach(person item in q)
{
//do something with q

}



هنوزم درست نفهمیدم...
من از بایندینگ استفاده نمیکنم.
آیا متد ToList یا ToArray و ... یا مثلا مرور رکورد ها با حلقه ها باعث میشه که قبلش کوئری ساخته بشه؟
فکر میکنم از اونجایی که extension متد های لینک همگی ienum و iquery بر میگردونن، تا زمانی که از این دیتاهای Ienumrable مون استفاده نکنیم، دیتایی خونده نمیشه:

var q=db.TestTable.AsIEnumrable();
q=q.Where(a=>a.id<100);
q=q.Take(10);
dg.DataSource=q.ToList(); // it couses reading from db
foreach(person item in q)
{
//q dobare khoonde mishe, faghat baraye yek bar,
//va na be ezaye har halghe yek bar
}


به نظر من چون تا زمان استفاده نکردن از اطلاعات دیتایی خونده نشده، به ازای دستورات بالا، کوئری ای شبیه زیر ساخته میشه که شرط و top در اون وجود داره.

select top 10 id, name ,... from testTable
where id<100

mpmsoft
شنبه 24 اردیبهشت 1390, 16:02 عصر
بهترین گزینه SQL Profiler هست