PDA

View Full Version : سوال: استفاده از StoreProcedure ی که دو فیلد برمی گرداند در Entity FrameWork



fa_karoon
چهارشنبه 12 تیر 1392, 16:36 عصر
سلام دوستان
من یک استور پروسی جر دارم که دو تا فیلد برمی گردونه یکی از اونها هم ترکیبی از دو فیلد هست که به هم چسبانده ام، حالا که از انتیتی استفاده می کنم یک Add Function می کنم و استروپروسی جرم رو تو پروژه ام اضافه کردم و نوع بازگشتی رو Complex تعریف کردم حالا می خوام جوری نتایج این استورپروسی جر رو برگردونم که به تک تک فیلدها و رکوردهاش دسترسی داشته باشم لطفا راهنمایی کنید؟
مرسی

Mahmoud.Afrad
چهارشنبه 12 تیر 1392, 16:58 عصر
با فراخوانی متد متناظر استورپروسیجر ، یک ObjectResult از نوع بازگشتی به شما میده که میتونید روی اون دوباره با لینک کوئری بزنید.
استور که با گرفتن آی دی مشخصات رو برمیگردونه را فرض کنید:

CREATE PROCEDURE SP_GetPerson
(
@id int
)
AS
/* SET NOCOUNT ON */
select FirstName + ' ' + LastName as FullName ,
FatherName
from tbl
where id = @id
RETURN

به اینصورت استفاده کنید:

int id = Convert.ToInt32(textBox1.Text);
var p = (from i in db.SP_GetPerson(id)
select i).SingleOrDefault();
//var p = db.SP_GetPerson(id).SingleOrDefault();
textBox2.Text = p.FullName;
textBox3.Text = p.FatherName;

در این استور یک آبجکت برگشت میشه به همین دلیل از SingleOrDefault استفاده کردم. اگر چند آبجکت باشه با یک حلقه میتونید استفاده کنید و یا به دیتاسورس کنترل ها نسبت بدید.

fa_karoon
پنج شنبه 13 تیر 1392, 20:09 عصر
ممنون دوست عزیز، حالا یه سوال دیگه من دارم از معماری سه لایه به همراه Entity FrameWork استفاده می کنم
آیا می شه تابعی در سطح DAL داشت شبیه چیزی که شما نوشتید با این تفاوت که اسم هر Store Procedure ی رو که خواستم با متغیرهاش به اون تابع بفرستم و این تابع اون رو اجرا کنه و بدون مشکل در نوع بازگشتی(چون ممکنه یه استور پروسی جر سه تا فیلد برگردونه دیگری 4 تا) نتیجه رو بده؟
وقتی از Ado استفاده می کردم تو پروژه ام توابع زیادی داشتم که چند تا پارامتر می گرفتن و کارهای زیادی رو با همون تابع پوشش می دادم، اما تو Entity احساس می کنم دستم بسته است البته شاید به خاطر عدم تسلطم هم باشه

Mahmoud.Afrad
جمعه 14 تیر 1392, 00:00 صبح
ممنون دوست عزیز، حالا یه سوال دیگه من دارم از معماری سه لایه به همراه Entity FrameWork استفاده می کنم
آیا می شه تابعی در سطح DAL داشت شبیه چیزی که شما نوشتید با این تفاوت که اسم هر Store Procedure ی رو که خواستم با متغیرهاش به اون تابع بفرستم و این تابع اون رو اجرا کنه و بدون مشکل در نوع بازگشتی(چون ممکنه یه استور پروسی جر سه تا فیلد برگردونه دیگری 4 تا) نتیجه رو بده؟
وقتی از Ado استفاده می کردم تو پروژه ام توابع زیادی داشتم که چند تا پارامتر می گرفتن و کارهای زیادی رو با همون تابع پوشش می دادم، اما تو Entity احساس می کنم دستم بسته است البته شاید به خاطر عدم تسلطم هم باشه
عملا لایه DAL همان مدل EF شماست. پس شما باید دو لایه باقیمانده رو بنویسید. یعنی مستقیما در لایه دوم(لایه Business) کوئری های لینک رو بنویسید. لایه سوم هم که از لایه دوم استفاده میکنه.

در اصل وقتی SP را به مدل Function Imports میکنید کار لایه DAL را انجام داده اید.

همون مثال پست قبلیم رو فرض کنید بخوایم سه لایه بنویسیم. خوب کافیه در لایه دوم متدی بصورت زیر داشته باشیم:

SP_GetPerson_Result GetPerson(string idStr)
{
int id;
try
{
id = int.Parse(idStr);
return db.SP_GetPerson(id).SingleOrDefault();
}
catch (Exception)
{
// log exception
// and then throw it
throw;
}
}

این متد یک آبجکت پس میفرسته؛ همونطور که می بینید نوع بازگشتی همونی هست که موقع import استورپروسیجر ساخته شده.
حالا در لایه سوم(لایه Presentation) به اینصورت استفاده میکنیم:

try
{
var q = GetPerson(textBox1.Text);
textBox2.Text = q.FullName;
textBox3.Text = q.FatherName;
}
catch (FormatException)
{
MessageBox.Show("فقط عدد وارد کنید");
}
catch (SqlException)
{
MessageBox.Show("در برقراری ارتباط با دیتابیس خطایی رخ داده است");
}



حالا اگر قرار باشه متدی که در لایه دوم مینویسیم، مقدار بازگشتیش چند آبجکت باشه میتونید خروجی رو از نوع IEnumerable از همان نوع بازگشتی بگیرید.
مثلا SP به نام SP_GetAllPerson را فرض کنید. بعد از Import کردن نوع بازگشتی SP_GetAllPerson_Result ساخته میشود. حالا در لایه دوم متد زیر را مینویسیم(به نوع بازگشتی توجه کنید):

IEnumerable<SP_GetAllPerson_Result> GetAllPerson()
{
try
{
return db.SP_GetAllPerson();
}
catch (Exception)
{
// log exception
// and then throw it
throw;
}
}

حالا در لایه سوم اینطوری استفاده میکنیم:

try
{
dataGridView1.DataSource = GetAllPerson();
}
catch (SqlException)
{
MessageBox.Show("در برقراری ارتباط با دیتابیس خطایی رخ داده است");
}

fa_karoon
جمعه 14 تیر 1392, 12:06 عصر
دوست عزیز لطفی رو که شما در حق من کردید با یه دکمه تشکر تنها نمی شه سپاسگزار بود، دقیقا در تعریف و استفاده توابعم در لایه های مختلف با حضور Entity مشکل داشتم واقعا ممنونم خیلی به درک من از قضیه کمک کردید. انشاء الله خدا اجرتون رو می ده. ممنون، موفق باشید