PDA

View Full Version : بهینه ترین روش تعریف متغییر های پایگاه داده



prince-of-persia
چهارشنبه 27 تیر 1386, 07:27 صبح
سلام

می خواستم بدونم بهینه ترین روش تعریف متغییر های پایگاه داده در asp.net 2 چیه ؟
در حال حاظر من در هر صفحه ایی که نیاز به استفاده از data base دارم متغییر هایی از نوع
sql connection
sql command
sql ds
, ...

تعریف می کنم که چندان جالب نیست . چطور می شه اینها رو تعریف کرد و در همه صفحات استفاده نمود ؟
در ضمن دردم که بعضی ها connection string رو در web.config تعریف می کنند . چرا و چگونه ؟

لطفا اگر کد دارید بگذارید و مبحث رو کمی کامل کنید چون این مشکل خیلی هاست اما چون سربار زیادی نداره راحت copy میکنند که البته اصلا حرفه ایی نیست .

با تشکر

Behrouz_Rad
چهارشنبه 27 تیر 1386, 09:47 صبح
متدهای دسترسی به پایگاه داده رو کپسوله کن. همین! منظور همان لایه ی DAL هست.
Connection String به این دلیل در Web.Config تعریف میشه تا در صورت لزوم برای تغییر اون نیازی به انجام اصلاح CN در تمامی پروژه نباشه. فقط کافیه این مقدار در Web.Config تغییر داده بشه.
یکی دیگه از دلایل تعریف CN در Web.Config، فعال سازی قابلیت Connection Pooling هست. (Undocumented)

موفق باشید.

fereshte22
چهارشنبه 27 تیر 1386, 14:57 عصر
اقای راد میشه لطف کنید و یک مثال در این مورد بزنید.
در ضمن اگر در مورد بقیه روش های که برای یک برنامه نویسی خوب و بهینه استفاده میشود اشاره ای داشته باشید ممنون میشوم.

prince-of-persia
چهارشنبه 27 تیر 1386, 16:22 عصر
منظور از کپسوله کردن چیست و چگونه باید این کار رو انجام داد .
اگر ممکن هست یک کد جمع و جور که منظور رو برسونه توی سایت بگذارید.

Behrouz_Rad
چهارشنبه 27 تیر 1386, 16:33 عصر
من همیشه پیشنهاد میکنم که به عنوان یک مثال ساده و جامع به Microsoft Aplication Data Block نگاهی بندازید.
Search About It

موفق باشید.

fereshte22
یک شنبه 31 تیر 1386, 11:48 صبح
من در مورد Microsoft Application Block for Data Access in .NET سرچ کردم کامپوننت اون را هم دانلود کردم ولی مسئله برام خیلی گنگ است و مثال هایی هم که دیدم کمکی به من نکرد.میشه دوستان یک مثال ساده در این مورد بزنند.تا من با مفهموم و اصول این روش اشنا شوم.و یا به عنوان مثال من کد زیر را قرار میدهم میشه من را راهنمایی کنید که با استفاده از این کامپوننت کد زیر و تعریف متغیرهای اون به چه صورت تغییر میکند
Dim con As New SqlConnection(ConfigurationManager.ConnectionStrin gs("ssgshopConnectionString").ConnectionString) Dim dr As SqlDataReader Dim cmdselect As SqlCommand con.Open() cmdselect = New SqlCommand("select *from register where email='" & cs.secure(TextBoxemail.Text) & "'", con) cmdselect.ExecuteNonQuery() con.Close()خیلی ممنون

Behrouz_Rad
یک شنبه 31 تیر 1386, 18:58 عصر
در بسته ای که داونلود کردی، فایل CHM ای وجود داره که به عنوان راهنمای این کلاس عمل میکنه.
مثال های خوبی داره و توضیحات کامل و جامعی در مورد اجزای این کلاس ارائه داده.

موفق باشید.

prince-of-persia
دوشنبه 01 مرداد 1386, 10:11 صبح
من هم بسته رو گرفتم اما در هر صفحه بازهم متغییر هایی که fereshteh گفته رو بازنویسی کرده.
اما من می خوام اونها رو یکبار بنویسم و چند با استفاده کنم . چه راهی هست.

Behrouz_Rad
دوشنبه 01 مرداد 1386, 10:37 صبح
من نمیدونم شما چی رو داونلود کردید اما یکی از مثال هایی که در اون برای پیاده سازی یک Action Query داره اینه:


[C#]

private bool performTransactionalUpdate(string connectionString,

string creditAccountNumber, string debitAccountNumber, decimal amount)

{

using ( SqlConnection conn = new SqlConnection(connectionString) )

{

conn.Open();

using ( SqlTransaction trans = conn.BeginTransaction() )

{

// Establish command parameters

// @AccountNo (From Account)

SqlParameter paramFromAcc = new SqlParameter("@AccountNo",

SqlDbType.Char, 20);

paramFromAcc.Value = debitAccountNumber;



// @AccountNo (To Account)

SqlParameter paramToAcc = new SqlParameter("@AccountNo",

SqlDbType.Char, 20);

paramToAcc.Value = creditAccountNumber;



// @Money (Credit amount)

SqlParameter paramCreditAmount = new SqlParameter("@Amount",

SqlDbType.Money );

paramCreditAmount.Value = amount;



// @Money (Debit amount)

SqlParameter paramDebitAmount = new SqlParameter("@Amount",

SqlDbType.Money );

paramDebitAmount.Value = amount;



try

{

// Perform the debit operation

SqlHelper.ExecuteNonQuery(trans, CommandType.StoredProcedure, "Debit",

paramFromAcc, paramDebitAmount );



// Perform the credit operation

SqlHelper.ExecuteNonQuery(trans, CommandType.StoredProcedure, "Credit",

paramToAcc, paramCreditAmount );



trans.Commit();

return true;

}



catch (Exception ex)

{

// Log details

trans.Rollback();

throw ex;

}

}

}

}


نام فایل CHM این بسته، DAAB.chm هست.

موفق باشید.

fereshte22
دوشنبه 01 مرداد 1386, 11:03 صبح
اقای راد من مثال های daab.chm را نگاه کردم ولی مسئله برام خیلی مبهم است.و درست متوجه نمیشوم.میتونم از شما در خواست کنم که روی همون مثال ساده ای که من گذاشتم این مسئله را توضیح دهیدخیلی لطف میکنید.

prince-of-persia
دوشنبه 01 مرداد 1386, 11:03 صبح
درسته اما توی همون فرم اول باز هم متغییر های conn و ... رو تعریف کرده نمی دونم چرا ؟

Behrouz_Rad
دوشنبه 01 مرداد 1386, 11:32 صبح
چون توابع این کلاس Overload های مختلفی دارن.
از یکی از Overload ها استفاده کن که نیاز به استفاده از کلاس های دیگه نداشته باشه.

موفق باشید.

fereshte22
دوشنبه 01 مرداد 1386, 14:12 عصر
اقای راد کاش روی همون مثال ساده ای که من گذاشته بودم این مسئله را پیاده سازی میکردیفکر کنم این طوری ما بهتر با این مفهوم آشنا میشدیمممنون

Behrouz_Rad
دوشنبه 01 مرداد 1386, 17:58 عصر
چیز عجیبی وجود نداره!
فایلی با نام SqlHelper وجود داره که تعدادی از اعمال متداول DML پایگاه داده رو کپسوله کرده تا نیاز به نوشتن مداوم کدها (شامل ایجاد Connection، Command و ...) رو نداشته باشید.

توضیح خاصی نیاز نداره.

موفق باشید.

fereshte22
سه شنبه 02 مرداد 1386, 11:52 صبح
آقای راد بابت راهنمای ها و پیگیریتون خیلی ممنون هستم.مسئله برام روشن شد .فقط مشکلی که دارم اینه که این Overloads را کجا باید تعریف کنیم.مثلا کد زیر را در نظر بگیرید


Dim strSql AsString = "select * from kala where "
Dim strConnTxt AsString = "Data Source=FERESHTE-BDE62C\SQLEXPRESS;Initial Catalog=ssgshop;Integrated Security=True"
GridView1.DataSource = SqlHelper.ExecuteReader(strConnTxt, CommandType.Text, strSql)
GridView1.DataBind()


از commandtype خطا میگیرد که تعریف نشده است.
و تابع اون به صورت زیر است.


Public Overloads Shared Function ExecuteNonQuery(
ByVal connection As SqlConnection, ByVal commandType As CommandType, _
ByVal commandText As String) As Integer



و سوال دیگرم اینه که این روش در واقع جایگزین همان روشی است که از کلاس برای این متغیرها استفاده میشد؟
و سوال اخرم اینه که اگه بخواهیم در مثال بالا connectionstring را در webconfig تعریف کنید به چه صورت باید عمل کنیم؟چون من هر مثالی دیدم connection در webconfig تعریف نشده بود.
ممنون و شرمنده

Behrouz_Rad
سه شنبه 02 مرداد 1386, 12:15 عصر
از commandtype خطا میگیرد که تعریف نشده است.
CommandType در نیم اسپیس Data تعریف شده.
Data.CommandType.Text

و سوال دیگرم اینه که این روش در واقع جایگزین همان روشی است که از کلاس برای این متغیرها استفاده میشد؟
بله.

و سوال اخرم اینه که اگه بخواهیم در مثال بالا connectionstring را در webconfig تعریف کنید به چه صورت باید عمل کنیم؟چون من هر مثالی دیدم connection در webconfig تعریف نشده بود.
به همان شکلی که قبلا نحوه ی تعریف CN در Web.Config و بکار گیری اون رو دیدی عمل کن.
همه چیز رو نیابد با مثال نشون داد.

موفق باشید.

fereshte22
چهارشنبه 03 مرداد 1386, 12:48 عصر
سلاماقای راد یه سوال دیگه برای من پیش اومده .من وقتی از یک نمونه کد به صورت زیر استفاده میکنم.مشکلی ندارد.
Dim sql As String = "SELECT TOP 10 * FROM kala ORDER BY number DESC " sql = "SELECT * FROM kala where nemayesh='" & cs.secure("true") & "'" GV.DataSource = SqlHelper.ExecuteReader(con, CommandType.Text, sql) GV.DataBind()ولی وقتی در ادامه کد بالا کد زیر را استفاده میکنم
Dim sql1 As String = "select *from sarshakheh " DataList2.DataSource = SqlHelper.ExecuteReader(con, CommandType.Text, sql1) DataList2.DataBind()روی خط دوم خطای زیر را میگیرد
An exception of type 'System.InvalidOperationException' occurred in Microsoft.ApplicationBlocks.Data.DLL but was not handled in user codeAdditional information: There is already an open DataReader associated with this Command which must be closed first.و وقتی در انتهای بایندینگ اول(گریدویو) از
con.Close()استفاده میکنم مشکل حل میشود.سوال من اینه چرا این مشکل پیش میاید؟ مگه کلاس sqlhelper باز و بستن کانکشن را در خودش ندارد؟

Behrouz_Rad
چهارشنبه 03 مرداد 1386, 14:57 عصر
در این کلاس یک Enum با نام SqlConnectionOwnership وجود داره که مشخص کننده ی نحوه ی مدیریت Connection هست.
دو مقدار Internal و External رو میپذیره.
Internal مشخص می کنه که مدیریت بسته شدن Connection بعد از فراخوانی ExecuteReader به طور خودکار توسط کلاس انجام بشه و External مشخص میکنه که این عمل باید توسط استفاده کننده از کلاس صورت بگیره.
نویسنده ی این کلاس اینجوری حال کرده که در برخی مواقع این کار رو به صورت خودکار انجام بده و در برخی مواقع به عهده ی Caller بگذاره.
اگر از Overload ای استفاده می کنی که نیاز به پاس دادن پارامترهای یک SP به اون هست، Internal فراخوانی میشه و در غیر اینصورت خودت باید پس از فراخوانی این متد، Connection رو ببندی.

موفق باشید.