PDA

View Full Version : سوال: مقایسه دو روش برنامه نویسی 3 لایه



behnam-soft
دوشنبه 26 اسفند 1392, 20:59 عصر
با سلام خدمت اساتید عزیز
من چند روزی هست که تکنیک برنامه نویسی 3 لایه رویاد گرفتم و از این بابت مشکلی هم نیست.روشی که من یاد گرفتم اینه که برای هر جدولی که در دیتا بیس داریم، 4 لایه درست می کنیم (Business Layer و InterFace layer و Data Layer و Parent Data Layer) و کدهایی که مربوط به چهار عمل اصلی هر جدولمون هست رو در لایه Parent Data Layer می نویسیم(که به نظرم خیلی حجم کدنویسی زیاد تر میشه !!!). اما در بعضی سایت های فارسی زبان و یا انگلیسی زبان، دیدم که طرف اومده کلا 3 لایه درست کرده، و تمام کدهایی که مربوط به هر نوع عمل دیتا بیس و جداول هست رو پیاده سازی کرده. در واقع خیلی حجم کدنویسی رو کاهش داده!

حالا سوالی که من از دوستان دارم اینه که به نظر شما الان کدوم روش مناسب تر و بهینه تره ؟ من فکر می کنم این روش اولی که من استفاده می کنم به یه نوعی 4 لایه میشه!!! انگار در روش دوم Parent Data Layer هیچ جایی نداره !!!
ممنون می شم راهنمایی کنین !

behnam-soft
دوشنبه 26 اسفند 1392, 21:00 عصر
ضمنا روش کارم با بانک هم ADO و Stored Procedure هست.

mahmoudii
دوشنبه 26 اسفند 1392, 21:25 عصر
من از روش دوم استفاده میکنم و به نظرم بهینه تر هست بخاطر تعداد خطوط کمتر در کدنویسی

behnam-soft
سه شنبه 27 اسفند 1392, 17:37 عصر
این آموزشی که من ازش استفاده کردم توسط یه فرد تقریبا حرفه ای پیاده سازی شده، حتما یه دلیلی داره که از روش اول استفاده کرده !

mahmoudii
سه شنبه 27 اسفند 1392, 18:20 عصر
معمول ترین روش دربرنامه نویسی سه لایه هست ، یه روش ثابت برای دسته بندی وجود نداره وفکر میکنم این به خود برنامه نویس برمیگرده که بخواد چند لایه کار کنه بعضیا سه لایه کار میکنن ، بعضیا چهار لایه و ...
اما در مورد اینکه کدوم روش بهتر هست من با توجه به تعداد خطوط کمتری که توی روش خودم استفاده میکنم نظر دادم در مورد نوع اول شاید بخاطر پیچیده کردن کدهاست که این کار رو انجام میدن و شاید این باعث امنیت بیشتر برنامه ها میشه
از دوستانی که در این زمینه میتونن مطمئن نظر بدن خواهش میکنم در مورد این سوال نظر بدن تا ابهاماتی که وجود داره برطرف بشه

mahmoudii
سه شنبه 27 اسفند 1392, 18:33 عصر
البته من یه جایی خونده بودم که یک لایه دیگه هم استفاده میکنن (Cache Layer )لایه ذخیره اطلاعات در حافظه کش هست که کش از حافظه کوتاه مدت استفاده می کنه و به همین خاطر بسیار سریعتر از دیتابیس( که روی هارد دیسک ذخیره می شه ) قابل دسترسیه که برخی اطلاعات پر استفاده که نیازی نداره به روز باشن رودر کش ذخیره میکنن که این لایه بین BLL و UI قرار میگیره تا UI به جای استفاده از اطلاعات تازه از کش اطلاعات رو واکشی کنه
نمیدونم این چیزی که شما میگین هم چیزی مثل این هست یا نه

behnam-soft
چهارشنبه 28 اسفند 1392, 15:12 عصر
من فکر نمی کنم این نوع برنامه نویسی(روش اول) کار رو پیچیده کنه! چرا که ما فقط میاییم به یه نوعی کد ها رو دسته بندی می کنیم نه اینکه مثلا نوع کد ها و یا شیوه ارتباط برقرار کردنمون رو تغییر بدیم! درسته ؟ ضمنا هر کسی یه ذره برنامه نویسی کار کرده باشه با دیدن کد ها به راحتی می تونه بفهمه که جریان چیه !!!

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

mahmoudii
چهارشنبه 28 اسفند 1392, 17:10 عصر
نه!!! طبق چیزی که من خونده بودم اینطور گفته شده بود
Cache اطلاعات رو در حافظه جانبی (RAM) ذخیره می کند بنابراین سرعت دسترسی و خوندن و نوشتن اطلاعات بسیار بالا میره
پس مکان مناسبی برای ذخیره اطلاعاتیه که به کرات درخواست می شه این لایه باعث میشه به جای اینکه اطلاعات به صورت مستقیم از دیتابیس درخواست بشه از کش خونده بشه .

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

plus
چهارشنبه 28 اسفند 1392, 17:34 عصر
لایه بندی، شاید در همه مسائلی که بحث دیتابیس و قوانین کاری هست، مفید باشه، اما برای جزئیتایش، هیچ استاندارد مشخص یا بهترین روشی به صورت کلی وجود نداره.
اون چیزی که روش بهتر رو مشخص میکنه، صورت مساله هست.برای یک مساله، ممکنه روش دوم کافی باشه، ولی شاید طراح روش اول، به دلیل که مربوط به صورت مساله میشه، یک لایه اضافه کرده.
مثلا شاید دلیل این بوده که در Data Access Layer، نیاز به فراخوانی چهار عمل اصلی موجودیت ها در جاهای مختفلی از DAL خیلی زیاد بوده و طراح برای کاهش کدهای تکراری، چهار عمل اصلی رو در یک لایه دیگه نوشته.در این حالت، این روش مفیده اما برای مساله ای که میزان این نیاز کم باشه، همونطور که گفتین میتونه موجب کدنویسی زیاد از حد و بی مورد و افزایش پیچیدگی بشه.
بنابراین، اگه شما صورت مساله رو میتونید با روش ساده تر حل کنید، نیازی نیست که بی جهت پیچیدگی کار رو بالا ببرید.هرچقدر تجربه شما در معماری و طراحی این جور مسائل بشتر بشه، بهتر میتونید با داشتن صورت مساله بفهمید که مثلا چند لایه نیاز هست...
در مورد Caching هم...Cache کردن اطلاعات میتونه در شرایطی مفید باشه، البته بدون شک به پیچیدگی کار اضافه میکنه.البته این که چه چیزی هم Cache بشه و در چه لایه ای متفاوت هست.
میتونید کتاب Patterns of Enterprise Application Architecture از انتشارات Addison Wesley رو مطالعه کنید.کتاب قدیمی هست (2002) اما نکات خوبی در این موارد توش پیدا میشه.

behnam-soft
چهارشنبه 06 فروردین 1393, 11:47 صبح
من با استفاده از روش دوم، یه برنامه تمرینی نوشتم که در آخر دیدم کلا لایه InterFace رو حذف کردم و عملا کاربردی در برنامه ام نداره ! می خواستم بدونم من روش رو اشتباه رفتم یا اینکه این روش هم می تونه اصولی باشه ؟
کد برنامه :
لایه dal

using System.Data;
using System.Data.SqlClient;

public class DAl
{
public DataTable ShowList()
{
SqlCon con = new SqlCon();
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter("shownews", con.OpenCon());
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.Fill(dt);
con.CloseCon();
return dt;
}
public int InsertDeleteUpdate(SqlCommand cmd)
{
SqlCon con = new SqlCon();
cmd.Connection = con.OpenCon();
int r = cmd.ExecuteNonQuery();
con.CloseCon();
return r;
}
}


لایه bll

using System.Data.SqlClient;
using System.Data;
public class BAL
{
public int DoCommand(SqlCommand cmd)
{
DAl d = new DAl();
return d.InsertDeleteUpdate(cmd);
}

public DataTable ShowList()
{
DAl d = new DAl();
return d.ShowList();
}
}

و لایه اینترفیس که اصلا در برنامه لازم نشد ازش استفاده کنم ! :

public class IntefaceLayer
{
public class tblnews
{
int id;
string title;
string date;
string newscontent;
string author;
int flag;
}
public class tblusers
{
int id;
string username;
string userpass;
int type;
}
}


و این کد پشت فرمم :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace My3LayerWayTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
BAL b = new BAL();
dataGridView1.DataSource = b.ShowList();
}

private void button1_Click(object sender, EventArgs e)
{
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "inserttblnews";
cmd.CommandType=CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@id",int.Parse(textBox1.Text));
cmd.Parameters.AddWithValue("@title",textBox2.Text);
cmd.Parameters.AddWithValue("@date",textBox3.Text);
cmd.Parameters.AddWithValue("@newscontent",textBox4.Text);
cmd.Parameters.AddWithValue("@author",textBox5.Text);
cmd.Parameters.AddWithValue("@flag",int.Parse(textBox6.Text));
BAL b = new BAL();
if (b.DoCommand(cmd) == 1)
MessageBox.Show("Yes!");
else
MessageBox.Show("No!");
Form1_Load(null,null);
}
}
}


البته یه کلاس هم برای ارتباط با بانکم نوشتم که میشه این :

using System;
using System.Data.SqlClient;

public class SqlCon
{
string constring = "";
Boolean State;
SqlConnection con = new SqlConnection();

public SqlConnection OpenCon()
{
if (!State)
{
constring = @"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Documents and Settings\Administrator\My Documents\NewsDB.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";
con.ConnectionString = constring;
con.Open();
State = !State;
}
return con;
}

public void CloseCon()
{
if (State)
{
con.Close();
State = !State;
}
else
return;
}
}



ممنون میشم دوستان اگر جایی نقطه ضعف و یا کمبودی میبینن بهم بگن.

behnam-soft
چهارشنبه 06 فروردین 1393, 21:04 عصر
دوستان نظری ندارن؟

mahmoudii
چهارشنبه 06 فروردین 1393, 22:05 عصر
تاپیکی تو همین تالار هست که به نظرم اگه خوب مطالبی که دوستان دراین تاپیک گفتن رو مطالعه کنین خودتون متوجه ایرادهایی که داشتین میشین

برنامه نویسی سه لایه (http://barnamenevis.org/showthread.php?418906-برنامه-نویسی-سه-لایه&highlight=برنامه+نویسی+چند+لایه)

behnam-soft
پنج شنبه 07 فروردین 1393, 12:45 عصر
ضمن تشکر ار لینکی که گذاشتین، من قبلا اکثر تاپیک هایی که مربوط به برنامه نویسی 3 لایه می شد رو خوندم اما خب هر کسی طبق روش خودش عمل کرده و این یه مقدار باعث بد فهمی من میشه. مثلا در خیلی از برنامه ها اصلا از لایه اینترفیس (مشابه اینترفیسی که من نوشتم-ایجاد فیلد های بانک بصورت پراپرتی های یک کلاس و پاس دادن اون به لایه های مورد نظر) استفاده نکردن یا اینکه اومدن مستقیم یه تکس باکسو به عنوان پارامتر ارسال کردن و ...
ممنون میشم اگر نقطه ضعفی در برنامه ای که خودم نوشتم دیدین، بگین. اینطوری بهتر می تونم مشکل رو درک کنم.

behnam-soft
یک شنبه 10 فروردین 1393, 09:27 صبح
امیدوارم کهنه شدن تاریخ پست قبلی به دلیل بی عیب بودن برنامه ای که نوشتم باشه!!!

behnam-soft
پنج شنبه 14 فروردین 1393, 21:17 عصر
یعنی از این همه برنامه نویس، واقعا کسی نیست ما رو راهنمایی کنه ؟؟؟

NASA's Spaceman
پنج شنبه 14 فروردین 1393, 22:00 عصر
دوست عزیز برو تو سایت ماکروسافت چک کن تا جواب بگیری یا برو تو انجمن ماکروسافت
بگمونم برنامه نویس های حرفه ای انجمن نمی خوان جواب سوالی بدن
با سپاس

r4hgozar
جمعه 15 فروردین 1393, 11:15 صبح
تا جایی که من تجربه دارم این تالار متاسفانه به سوالات مهم جواب نمی ده. خودم هم نمی دونم چرا.

اما اگه به سایت http://stackoverflow.com/ سر بزنین و سوال کنین خیلی راحت تر می تونین جوابتون رو بگیرین.
البته اگه انگلیسیتون خوب باشه

mahmoudii
شنبه 16 فروردین 1393, 13:04 عصر
سلام دوست عزیز من چند مورد از ایرادهایی که به نظرم رسید رو براتون میگم :
اول اینکه در dal که لایه ارتباط با دیتابیس هست متد اولی که نوشتین جا لب نیست
اگه قصدتون سه لایه نویسی هست پس باید حتما یه دسته بندی مشخصی برای این کار داشته باشین که بتونین از لایه ها و متد هایی که در این پروژه مینویسین در پروژه های دیگه هم استفاده کنین
شما در dal یک متد showlist تعریف کردین و استورد پروسیجر رو هم همینجا بهش معرفی کردین و این کار درستی از نظر ساختار dal نیست چرا که کار این لایه ارتباط با بانک و اجرای دستورات هست و شما خود دستورات یا استورد پروسیجر رو باید در bll معرفی کنین
ودوم اینکه اون کلاسی هم که برای بانک نوشتین رو میتونستین در همین لایه بنویسین و نیاز نبود که یک کلاس جداگانه برای بانک ایجاد کنین چون جزو وظایف همین لایه هست
پس در اینجا بهتره یک متد تعریف کنین برای کل select ها
در مورد Bllهم شما چیز خاصی ننوشتین اما در کل داخل این لایه متدهای addو update و deleteو برای نمایش هم مثلا همون show نوشته میشه و اجرای اونها به dllواگذار میشه
درلایه اینترفیس که میگین به دردتون نخورد در واقع این لایه همون کدهای پشت فرمتون هست و لایه جدایی برای اون در نظر نمیگیرن و به همون کدهای پشت فرم میگن لایه اینترفیس
در این لایه شما برای insert کد نوشتین که درستش این بود که این کار رو در bll انجام بدین چرا که این لایه (اینترفیس) کمترین کد رو داره و فقط متدهای bllرو فراخوانی میکنه
در کل ایرادی که وجود داشت در دسته بندی نشدن درست لایه ها بود

mahmoudii
شنبه 16 فروردین 1393, 13:27 عصر
باز هم بهتون پیشنهاد میکنم که اون تاپیکی که در بالا بهتون معرفی کردم رو خوب بخونین مطمئن باشین اگه مفید نبود بهتون معرفیش نمیکردم
مخصوصا از پست نهم به بعد دراین تاپیک دوستان نکات خوبی رو اشاره کردن که حتما میتونه بهتون کمک کنه

behnam-soft
یک شنبه 17 فروردین 1393, 23:27 عصر
اول اینکه در dal که لایه ارتباط با دیتابیس هست متد اولی که نوشتین جا لب نیست
اگه قصدتون سه لایه نویسی هست پس باید حتما یه دسته بندی مشخصی برای این کار داشته باشین که بتونین از لایه ها و متد هایی که در این پروژه مینویسین در پروژه های دیگه هم استفاده کنین

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



شما در dal یک متد showlist تعریف کردین و استورد پروسیجر رو هم همینجا بهش معرفی کردین و این کار درستی از نظر ساختار dal نیست چرا که کار این لایه ارتباط با بانک و اجرای دستورات هست و شما خود دستورات یا استورد پروسیجر رو باید در bll معرفی کنین

با این حرفتون موافقم، و فکر می کنم اینطوری لایه DAl هم انعطاف پذیر تر می شه.اما اینکه آیا کار راه انداز خواهد بود یا خیر رو، نظری ندارم.ولی اگه اینطور باشه که شما میگین، پس لایه DAL کلا 2 تا متد نباید بیشتر داشته باشه چرا ؟ چون یه متد می نویسیم برای Insert,Delete,UpDate و یک متد هم برای Select !!! البته اگر شما مخالف این هستید ممنون میشم دلیلتون رو بگین .




و دوم اینکه اون کلاسی هم که برای بانک نوشتین رو میتونستین در همین لایه بنویسین و نیاز نبود که یک کلاس جداگانه برای بانک ایجاد کنین چون جزو وظایف همین لایه هست

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



در مورد Bllهم شما چیز خاصی ننوشتین اما در کل داخل این لایه متدهای addو update و deleteو برای نمایش هم مثلا همون show نوشته میشه و اجرای اونها به dllواگذار میشه.
درلایه اینترفیس که میگین به دردتون نخورد در واقع این لایه همون کدهای پشت فرمتون هست و لایه جدایی برای اون در نظر نمیگیرن و به همون کدهای پشت فرم میگن لایه اینترفیس.

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

با این اوصاف، از تموم اطلاعاتم در مورد برنامه نویسی 3 لایه که برجی ساخته بودم رو باید فرو بریزم و از نو بنا کنم! چون هر کسی اومده با یه روشی و دلیلی پیش رفته! البته من نسخه جدید کد هارو با این اطلاعاتی که شما دادین می نویسم و اینجا قرار می دم تا هم اینکه روش بحث کنیم و به دید کلی برسیم، هم اینکه دوستان هم استفاده کنن.با تشکر

mahmoudii
دوشنبه 18 فروردین 1393, 12:49 عصر
منظور من این نبود که همیشه دقیقا همین متد ها رو استفاده میکنین، به دلیل ساختار مشترکشون با کمی تغییرات میشه ازشون در پروژه های دیگه به راحتی استفاده کرد

mahmoudii
دوشنبه 18 فروردین 1393, 12:50 عصر
در مورد سوال دوم هم باید بگم بله ، میتونین به این شکل کدش رو در dal بنویسید
public DataTable AllSelect(SqlDataAdapter da) {
da.SelectCommand.Connection = con;
da.SelectCommand.CommandType = CommandType.StoredProcedure;
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}

mahmoudii
دوشنبه 18 فروردین 1393, 12:52 عصر
وبرای نوشتن متدش هم درbllبه این صورت عمل کنید

public DataTable ShowList() {
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = new SqlCommand();
da.SelectCommand.CommandText = "shownews";
DataTable dt = new DataTable();
dt = dl.AllSelect(da);
return dt;
}

mahmoudii
دوشنبه 18 فروردین 1393, 12:55 عصر
در مورد قسمت آخر صحبتتونم که گفتین در بعضی روش ها میان تمام فیلدها رو در یک کلاس قرار میدن درست
اما آیا شما وقتی از استوردپروسیجر استفاده میکنین نیازی به تعریف فیلدهای بانک در این کلاس دارید؟!
بازم همونطور که قبلا گفتم میگم که اینکه چند لایه برای پروژه در نظر بگیرن به خود برنامه نویس برمیگرده و من با توجه به نمونه ای که اینجا قرار دادین صحبت کردم
شاید اون آموزشی که شما دیدین روش کدنویسیش اونطور بود که نیاز به تعریف کلاس جداگانه برای فیلدهای بانک بود و نمیشه بهش ایراد گرفت
ولی اگه طبق کاری که شما کردین در کدهای پشت فرم خودش به این شکل عمل کرده که شما برای باتن 1 کدنویسی کردین دیگه بهش نمیگن چند لایه کار کردن !

mahmoudii
دوشنبه 18 فروردین 1393, 12:58 عصر
نگران نباشین ، در کل هدف همه روشها یکیه و نحوه پیاده سازیش مقداری فرق داره که تشخیص دلیل استفاده اونها از روششون هم چیز سختی نیست این نمونه کدی که قرار دادین نشون میده که شما یه مقداری گیج شدین
اگه واقعا هدف اون آموزش یاد دادن برنامه نویسی چند لایه بوده باشه فکر نمیکنم پشت فرم برای یه دکمه به این صورت عمل کرده باشه اگه اینطور بوده اون آموزش رو فراموش کنین و به قول خودتون برجی که ازش ساختین رو فروبریزین
اما اگه اینطور نبوده ، اینکه آموزشهای مختلف و روشهای مختلف رو ببینین خیلی هم بهتون در درک این موضوع کمک میکنه البته قبل از دیدن روشهای مختلف سعی کنین به یه روش مسلط بشین
موفق باشید

esafb52
دوشنبه 18 فروردین 1393, 16:27 عصر
ضمنا روش کارم با بانک هم ADO و Stored Procedure هست.
من یه نمونه سه لایه که خودم کار میکنم رو میذارم



//بسم الله الرحمن الرحیم
//الهم صلی علی محمد وآل محمد

using System;
using System.Data;
using System.Data.SQLite;

namespace danshjo
{
public class dal
{

public SQLiteConnection con = new SQLiteConnection("Data Source=fule.rar;version=3");

public void conect()
{
con.Open();
}

public void disconect()
{
con.Close();

}
//اجرای تمام دستورات SQL
public void AllCommand(SQLiteCommand command)
{
command.Connection = con;
conect();
command.ExecuteNonQuery();
disconect();
command.Dispose();

}

// اجرای تمام دستورات برای گرفتن سطرها SQL
public int rowscount(SQLiteCommand command)
{
command.Connection = con;
conect();
int result = Convert.ToInt32(command.ExecuteScalar());
disconect();
command.Dispose();
return result;
}
//برای پر کردن تمام گریدو....ها
public DataTable AllSelect(SQLiteDataAdapter dataAdapter)
{
dataAdapter.SelectCommand.Connection = con;
DataTable dt = new DataTable();
dataAdapter.Fill(dt);
return dt;
}


}
}



لایه دوم

using System;
using System.Data;
using System.Data.SQLite;

namespace danshjo
{
public class bal
{
dal db = new dal();

public DataTable LoadAllmain()
{
string cmd = "select * from tblfule ORDER BY lastname LIMIT 18";
SQLiteDataAdapter da = new SQLiteDataAdapter();
da.SelectCommand = new SQLiteCommand();
da.SelectCommand.CommandText = cmd;
DataTable dtaTable = db.AllSelect(da);
return dtaTable;
}
//count of databse rows
public int rowscount()
{
string cmdcommnad = "select count(*) from tblfule";
SQLiteCommand command = new SQLiteCommand(cmdcommnad);
int result = Convert.ToInt32(db.rowscount(command));
return result;

}
//for serach in database by code mli
public DataTable LoadAllbycodemli(string codemli)
{
string cmd = "select * from tblfule Where codemli like '" + codemli + "%' order by name LIMIT 18";
SQLiteDataAdapter da = new SQLiteDataAdapter();
da.SelectCommand = new SQLiteCommand();
da.SelectCommand.CommandText = cmd;
DataTable dtaTable = db.AllSelect(da);
return dtaTable;
}
//for serach in database by code lastname

public DataTable LoadAllbylastname(string lastname)
{
string cmd = "select * from tblfule Where lastname like '" + lastname + "%' order by name LIMIT 18";
SQLiteDataAdapter da = new SQLiteDataAdapter();
da.SelectCommand = new SQLiteCommand();
da.SelectCommand.CommandText = cmd;
DataTable dtaTable = db.AllSelect(da);
return dtaTable;
}
//for delete person
public void deleteperson(string idcurentrow)
{
string cmdcommnad = "DELETE FROM tblfule WHERE codemli=@p1 ";
SQLiteCommand command = new SQLiteCommand(cmdcommnad);
command.Parameters.AddWithValue("@p1", idcurentrow);
db.AllCommand(command);
}
//for edit person

public void EditPerson(string name, string lastname, string codemli, string pass, string username, string fuletype, string fuleusing, string fulecount, string id)
{
string cmdcommand = "Update tblfule set name=@1,lastname=@2" +
",codemli=@3,pass=@4,username=@5," +
"fuletype=@6,count=@7,usingfule=@8 Where " +
"codemli=@id";
SQLiteCommand cmd = new SQLiteCommand(cmdcommand);
cmd.Parameters.AddWithValue("@1", name.Trim());
cmd.Parameters.AddWithValue("@2", lastname.Trim());
cmd.Parameters.AddWithValue("@3", codemli.Trim());
cmd.Parameters.AddWithValue("@4", pass.Trim());
cmd.Parameters.AddWithValue("@5", username.Trim());
cmd.Parameters.AddWithValue("@6", fuletype.Trim());
cmd.Parameters.AddWithValue("@8", fulecount.Trim());
cmd.Parameters.AddWithValue("@7", fuleusing.Trim());
cmd.Parameters.AddWithValue("@id", id);
db.AllCommand(cmd);

}


public void AddPerson(string name, string lastname, string codemli, string pass, string username, string fuletype, string fuleusing, string fulecount)
{


string cmdcommand = "INSERT INTO tblfule" +
" (name,lastname,codemli,pass,username,fuletype,coun t,usingfule)" +
" values(@1,@2,@3,@4,@5,@6,@7,@8)";
SQLiteCommand cmd = new SQLiteCommand(cmdcommand);
cmd.Parameters.AddWithValue("@1", name.Trim());
cmd.Parameters.AddWithValue("@2", lastname.Trim());
cmd.Parameters.AddWithValue("@3", codemli.Trim());
cmd.Parameters.AddWithValue("@4", pass.Trim());
cmd.Parameters.AddWithValue("@5", username.Trim());
cmd.Parameters.AddWithValue("@6", fuletype.Trim());
cmd.Parameters.AddWithValue("@7", fulecount.Trim());
cmd.Parameters.AddWithValue("@8", fuleusing.Trim());
db.AllCommand(cmd);

}
//frm tell method

public void Addphonenuber(string name, string number)
{
string cmdcommnad = "INSERT INTO tbltell (adareh,tell) values(@1,@2)";
SQLiteCommand command = new SQLiteCommand(cmdcommnad);
command.Parameters.AddWithValue("@1", name.Trim());
command.Parameters.AddWithValue("@2", number.Trim());
db.AllCommand(command);
}
public void Editphonenuber(string name, string number, string id)
{
string cmdcommnad = "Update tbltell set adareh=@1,tell=@2 where id=@id";
SQLiteCommand command = new SQLiteCommand(cmdcommnad);
command.Parameters.AddWithValue("@1", name.Trim());
command.Parameters.AddWithValue("@2", number.Trim());
command.Parameters.AddWithValue("@id", id);
db.AllCommand(command);
}
public DataTable LoadAlltellphone()
{
string cmd = "select * from tbltell ";
SQLiteDataAdapter da = new SQLiteDataAdapter();
da.SelectCommand = new SQLiteCommand();
da.SelectCommand.CommandText = cmd;
DataTable dtaTable = db.AllSelect(da);
return dtaTable;
}

//frmpass method
public DataTable LoadAlluser()
{
string cmd = "select * from tbluser ";
SQLiteDataAdapter da = new SQLiteDataAdapter();
da.SelectCommand = new SQLiteCommand();
da.SelectCommand.CommandText = cmd;
DataTable dtaTable = db.AllSelect(da);
return dtaTable;
}

public void ChngePassword(string username, string pass, string id)
{
string cmdcommnad = "Update tbluser set user=@1,pass=@2 where id=@id";
SQLiteCommand command = new SQLiteCommand(cmdcommnad);
command.Parameters.AddWithValue("@1", username.Trim());
command.Parameters.AddWithValue("@2", pass.Trim());
command.Parameters.AddWithValue("@id", id);
db.AllCommand(command);
}

// frmmadark method LoadAll
public DataTable LoadAllmadark()
{
string cmd = "select DISTINCT * from tblpic ORDER BY name";
SQLiteDataAdapter da = new SQLiteDataAdapter();
da.SelectCommand = new SQLiteCommand();
da.SelectCommand.CommandText = cmd;
DataTable dtaTable = db.AllSelect(da);
return dtaTable;
}

//frmloading method
public int chekpass(string username, string pass)
{
string cmdcommand = "select * from tbluser where user='" + username + "' and pass='" + pass + "'";
SQLiteCommand command = new SQLiteCommand(cmdcommand);
int result = Convert.ToInt32(db.rowscount(command));
return result;
}


//frmfuleusing method
public DataTable LoadAllfuleusing()
{
string cmd = "select * from tbl2 ORDER BY id";
SQLiteDataAdapter da = new SQLiteDataAdapter();
da.SelectCommand = new SQLiteCommand();
da.SelectCommand.CommandText = cmd;
DataTable dtaTable = db.AllSelect(da);
return dtaTable;
}

public void Addfuleusing(string name)
{
string cmdcommnad = "INSERT INTO tbl2 (fuleusingtype) values(@1)";
SQLiteCommand command = new SQLiteCommand(cmdcommnad);
command.Parameters.AddWithValue("@1", name.Trim());
db.AllCommand(command);
}
public void Editfuleusing(string name, string id)
{
string cmdcommnad = "update tbl2 set fuleusingtype=@1 Where id=@id";
SQLiteCommand command = new SQLiteCommand(cmdcommnad);
command.Parameters.AddWithValue("@1", name.Trim());
command.Parameters.AddWithValue("@id", id);
db.AllCommand(command);
}


//frmfuletype method
public DataTable LoadAllfuletype()
{
string cmd = "select * from tbl3 ORDER BY id";
SQLiteDataAdapter da = new SQLiteDataAdapter();
da.SelectCommand = new SQLiteCommand();
da.SelectCommand.CommandText = cmd;
DataTable dtaTable = db.AllSelect(da);
return dtaTable;
}

public void Addfrmfuletype(string name)
{
string cmdcommnad = "INSERT INTO tbl3 (fuletype) values(@1)";
SQLiteCommand command = new SQLiteCommand(cmdcommnad);
command.Parameters.AddWithValue("@1", name.Trim());
db.AllCommand(command);
}
public void Editfrmfuletype(string name, string id)
{
string cmdcommnad = "update tbl3 set fuletype=@1 Where id=@id";
SQLiteCommand command = new SQLiteCommand(cmdcommnad);
command.Parameters.AddWithValue("@1", name.Trim());
command.Parameters.AddWithValue("@id", id);
db.AllCommand(command);
}

}
}

و این یه نمونه استفاده در لایه سوم
using System;
using System.Drawing;
using System.Windows.Forms;

namespace danshjo
{
public partial class frmadd : Form
{

private int a = 0;

// SQLiteTransaction transaction; just for test

bal db= new bal();

public frmadd()
{
InitializeComponent();

}

private void btnadd_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtcodemli.Text) || string.IsNullOrEmpty(txtlastname.Text) ||
string.IsNullOrEmpty(txtuser.Text) || string.IsNullOrEmpty(txtpass.Text) ||
string.IsNullOrEmpty(txtname.Text) ||txtcodemli.Text.Trim().Length < 10)
{
MessageBox.Show("موارد خواسته شده را وارد نمایید");
txtname.Focus();
return;
}
else
{
try
{
db.AddPerson(
txtname.Text,
txtlastname.Text,
txtcodemli.Text,
txtpass.Text,
txtuser.Text,
cmbfuletype.Text,
cmbfuleusing.Text,
txtcountfule.Text);
a++;
frmmain.chnge++;
txtname.Focus();
tools.cleratxtbox(groupBox1);
MessageBox.Show("با موفقیت درج شد");


}
catch(Exception exception)
{
//transaction.Rollback();
MessageBox.Show("کد ملی وارد شده تکراری است");
MessageBox.Show(exception.Message);
txtname.Focus();
}

}
}

private void frmadd_Load(object sender, EventArgs e)
{
tools.farsikeybord();
cmbfuleusing.DataSource =db.LoadAllfuleusing();
cmbfuleusing.DisplayMember = "fuleusingtype";
cmbfuletype.DataSource =db.LoadAllfuletype();
cmbfuletype.DisplayMember = "fuletype";
}

private void frmadd_FormClosing(object sender, FormClosingEventArgs e)
{
if (a != 0)
{
DialogResult = DialogResult.OK;
}
}

private void textBox3_KeyPress(object sender, KeyPressEventArgs e)
{
if (!(char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar)))
{
e.Handled = true;
}
}

private void textBox4_KeyPress(object sender, KeyPressEventArgs e)
{
}

private void textBox4_TextChanged(object sender, EventArgs e)
{

}



private void textBox7_KeyDown(object sender, KeyEventArgs e)
{
TextBox txt = sender as TextBox;
if (e.KeyCode == Keys.Return)
SendKeys.Send("{TAB}");
}

private void comboBox1_KeyDown(object sender, KeyEventArgs e)
{
ComboBox cmb = sender as ComboBox;
if (e.KeyCode == Keys.Return)
SendKeys.Send("{TAB}");
}

private void textBox7_Enter(object sender, EventArgs e)
{
TextBox txt = sender as TextBox;
txt.BackColor = Color.Yellow;

}

private void comboBox2_Enter(object sender, EventArgs e)
{
ComboBox cmb = sender as ComboBox;
cmb.BackColor = Color.Yellow;
}

private void comboBox2_Leave(object sender, EventArgs e)
{

}

private void textBox7_Leave(object sender, EventArgs e)
{
TextBox txt = sender as TextBox;
if (string.IsNullOrEmpty(txt.Text))
{
txt.BackColor = Color.Red;
}

}

private void textBox4_Enter_1(object sender, EventArgs e)
{
tools.englishkyebord();
txtuser.BackColor = Color.Yellow;
}

private void textBox5_Leave(object sender, EventArgs e)
{
tools.farsikeybord();
TextBox txt = sender as TextBox;
if (string.IsNullOrEmpty(txt.Text))
{
txt.BackColor = Color.Red;
}
}

private void textBox3_Leave(object sender, EventArgs e)
{
TextBox txt = sender as TextBox;
if (string.IsNullOrEmpty(txt.Text) || txt.Text.Length > 10)
{
txt.BackColor = Color.Red;
}
}

private void textBox7_KeyPress(object sender, KeyPressEventArgs e)
{
if (!(char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar)))
{
e.Handled = true;
}
}
}
}

behnam-soft
چهارشنبه 20 فروردین 1393, 18:55 عصر
با تشکر از دوستانی که با نظرات و کد هاشون بنده رو یاری کردن، چند تا مورد به ذهنم میرسه که :

1-با توجه به بررسی هایی که کردم، فکر می کنم استفاده ار روش اول - که در پست اول ذکر شد - صرفا به درد پروژه های بزرگ می خوره، چرا که حجم کد نویسی در هر لایه به طور چشمگیری کاهش پیدا می کنه و پر واضحه که نمونه سازی ها هم بسیار سریعتر اتفاق می افته.

2-همونطور که می دونین، از لایه DAL صرفا برای ارتباط با بانک استفاده میشه، خب، در این لایه ما کلا 4 یا 5 تا متد داریم، به نظر شما بهتر نیست برای افزایش سرعت نمونه سازی، و در کل سرعت برنامه، بیاییم این چند تا متد رو هم در لایه BLL پیاده کنیم؟ هر چند که شاید این کار باعث زیر سوال رفتن مفهوم 3 لایه نویسی بشه.اما شما فرض از این لایه ها، می خواین در یک سایت که همزمان چند هزار نفر دارن سرویس می گیرن استفاده کنین! اینکار به معنای چند هزار نمونه سازی کمتر، و شاید چند هزار واحد افزایش سرعت خواهد بود! هر چند که نمی دونم این افزایش سرعت آیا قابل احساس خواهد بود و باعث حفظ منابع سرور خواهد شد؟

3- آیا راهی وجود داره که بشه از طریق کد نویسی یا روش دیگه ای، زمان و حافظه مصرف شده رو در هر نمونه سازی از لایه ها بدست آورد؟

چند روزی هست که سایت پاسخگوی درخواست هایی که به سرور منتقل میشه نیست، شما هم این مشکل رو دارین یا فقط برای منه؟

behnam-soft
جمعه 22 فروردین 1393, 22:55 عصر
راستی دوستان کد جنریتوری برای تولید 3 لایه سراغ دارن؟

behnam-soft
یک شنبه 24 فروردین 1393, 14:49 عصر
بله...همچنان منتظر راهنمایی دوستان هستیم...

behnam-soft
سه شنبه 02 اردیبهشت 1393, 18:55 عصر
هر چند که دوستان خیلی وقته که این تاپیک رو بی جواب گذاشتن، اما من یه سوال دیگه هم برام پیش اومده!!!
مگر قرار نیست روش 3 لایه نویسی، انحضار ما رو در استفاده هر نوع از بانکی رو لغو کنه؟ یعنی این که فرض کنید بانک من Acces باشه که دستورات ارتباط با بانکش در لایه DAl پیاده شده درست ؟
حالا بانک من تغییر پیدا کرده و از SQL Server استفاده می کنم، خب، طبق تعاریف 3 لایه نویسی، باید صرفا با تغییر لایه DAL که به راحتی هم صورت میگیره، بتونم کارهای قبل رو با بانکم انجام بدم
اگر تا به اینجای کار در تعاریف مشکلی نیست سوالم رو مطرح می کنم و اون این که : من هم دارم از همون روش 3 لایه ای استفاده می کنم که دوستمون esafb52 (http://barnamenevis.org/member.php?113083-esafb52) استفاده می کنن. خب حالا اگر بانکم به هر دلیلی تغییر کنه، من مجبورم که تمام متد های لایه BLL هم رو عوض کنم!!! که این یعنی کلا باید کد ها رو بجز لایه InterFace از نو نوشت!!! پس با این حساب یا روش ما اشکال داره، یا 3 لایه نویسی کمکی به این روش نمی کنه ! چون ما از دستورات SQL هم در لایه BLL استفاده کردیم!!!

plus
سه شنبه 02 اردیبهشت 1393, 20:48 عصر
هر چند که دوستان خیلی وقته که این تاپیک رو بی جواب گذاشتن، اما من یه سوال دیگه هم برام پیش اومده!!!
مگر قرار نیست روش 3 لایه نویسی، انحضار ما رو در استفاده هر نوع از بانکی رو لغو کنه؟ یعنی این که فرض کنید بانک من Acces باشه که دستورات ارتباط با بانکش در لایه DAl پیاده شده درست ؟
حالا بانک من تغییر پیدا کرده و از SQL Server استفاده می کنم، خب، طبق تعاریف 3 لایه نویسی، باید صرفا با تغییر لایه DAL که به راحتی هم صورت میگیره، بتونم کارهای قبل رو با بانکم انجام بدم
اگر تا به اینجای کار در تعاریف مشکلی نیست سوالم رو مطرح می کنم و اون این که : من هم دارم از همون روش 3 لایه ای استفاده می کنم که دوستمون esafb52 (http://barnamenevis.org/member.php?113083-esafb52) استفاده می کنن. خب حالا اگر بانکم به هر دلیلی تغییر کنه، من مجبورم که تمام متد های لایه BLL هم رو عوض کنم!!! که این یعنی کلا باید کد ها رو بجز لایه InterFace از نو نوشت!!! پس با این حساب یا روش ما اشکال داره، یا 3 لایه نویسی کمکی به این روش نمی کنه ! چون ما از دستورات SQL هم در لایه BLL استفاده کردیم!!!
خیلی منطقی به نظر نمیاد که در لایه Business از دستورات SQL استفاده کنید.در این صورت اونوقت نقش لایه Data Acces چیه؟ Open و Close کردن Connection ؟!
این یک نمونه سه لایه از عمل درج کاربر در سیستم:


Application/Presentaion Layer:

User user = new User();
user.Active = activeField.Value; // Active combobox
user.Username = usernameField.Value; // Username textbox
user.Password = passwordField.Value; // Password textbox
..
..
..
UserManager userManager = new UserManager();
userManager.Add(user);

// Business Layer:
class UserManager : ...
{
public User Add(User user)
{
if (user == null) {
throw new ArgumentNullException("user");
}
..
..
..
using (IDbContext context = CreateDbContext(true)) {
// Update user in db
user.CreatedBy = currentUser;
user.CreatedDate = DateTimeP.NowAsUtc;
user.ModifiedBy = currentUser;
user.ModifiedDate = DateTimeP.NowAsUtc;
user.Type = UserType.Administrator;
user.Title = user.Username;
UserRepository repository = new UserRepository(context);
user = repository.Insert(user);
..
..
..
// Commit transaction
context.SaveChanges();
return user;

}
}
..
..
..

}

// Data Access Layer
class UserResository : ...
..
..
..
public User Insert(User user)
{
if (user == null) {
throw new ArgumentNullException("user");
}
if (user == null) {
throw new ArgumentNullException("user.Username");
}
if (user.Active == null) {
throw new ArgumentNullException("user.Active");
}
if (user.CreatedBy == null) {
throw new ArgumentNullException("user.CreatedBy");
}
if (user.ModifiedBy == null) {
throw new ArgumentNullException("user.ModifiedBy");
}
if (user.Password == null) {
throw new ArgumentNullException("user.Password");
}
IDbCommand command = context.CreateCommand();
command.CommandText = "INSERT INTO Sys_UserTable (Username, Password, Title, Active, " +
"TypeId, CreatedBy, CreatedDate, ModifiedBy, ModifiedDate) " +
"VALUES (@Username, @Password, @Title, @Active, @TypeId, @CreatedBy, @CreatedDate, " +
"@ModifiedBy, @ModifiedDate)";

command.AddParameter("Active", user.Active);
command.AddParameter("CreatedBy", user.CreatedBy);
command.AddParameter("CreatedDate", user.CreatedDate);
command.AddParameter("ModifiedBy", user.ModifiedBy);
command.AddParameter("ModifiedDate", user.ModifiedDate);
command.AddParameter("Password", user.Password);
command.AddParameter("RowVersion", user.Version);
command.AddParameter("Title", user.Title);
command.AddParameter("TypeId", user.Type);
command.AddParameter("Username", user.Username);
try {
command.ExecuteNonQuery();
command.CommandText = "SELECT RowVersion FROM Sys_UserTable WHERE Username=@Username";
user.Version = (byte[])command.ExecuteScalar();
return user;
}
catch (Exception e) {
throw new DataAccessException(DataAccessError.DataAccessErro r, e);
}

}
}

plus
سه شنبه 02 اردیبهشت 1393, 20:50 عصر
(پست تکراری)

behnam-soft
چهارشنبه 03 اردیبهشت 1393, 22:51 عصر
ممنون از برنامه اي که گذاشتين، در واقع شما از هيچ دستور اس کيو ال ايي در لايه bll استفاده نکردي، به جاي اون اومدي تمام دستورات مربوط به بانک رو در لايه Dal نوشتي، خب، فکر مي کنم اين کار شما درست تره، اما اگر به ساختار کد هايي که دوستمون esafb52 نوشتن نگاه کنيد، مي بينيد که ما کلا يه متد براي حذف،درج و آپديت داريم و يه متد هم براي دستور Select که بسيار بسيار حجم لايه Dal رو کاهش ميده، در عوض يه سري دستورات رو در لايه BLL نوشتيم که در کل شايد از تعداد خطوط کدهايي که مي نويسيم کم کنه، اما اگر يه وقت قرار باشه بانک عوض بشه، محبوريم که لايه هاي DAL و BLL رو تغيير بديم که قطعا کار رو شايد کمي زمان بر کنه!

درکل، فکر مي کنم اگر مطمئن هستيم که بانکمون قرار نيست عوض بشه- که شايد خيلي هم کم اتفاق بيوفته - مي تونيم از روشي که esafb52 استفاده ميکنه، استفاده کنيم، هر چند که يک مقدار مفاهيم و تعابير و استاندارد برنامه نويسي 3 لايه رو زير سوال ميبره، اما اگر لازم بود روزي بانک نرم افزارمون عوض بشه، قطعا روش شما کار رو ساده تر خواهد کرد!

plus
چهارشنبه 03 اردیبهشت 1393, 23:18 عصر
ممنون از برنامه اي که گذاشتين، در واقع شما از هيچ دستور اس کيو ال ايي در لايه bll استفاده نکردي، به جاي اون اومدي تمام دستورات مربوط به بانک رو در لايه Dal نوشتي، خب، فکر مي کنم اين کار شما درست تره، اما اگر به ساختار کد هايي که دوستمون esafb52 نوشتن نگاه کنيد، مي بينيد که ما کلا يه متد براي حذف،درج و آپديت داريم و يه متد هم براي دستور Select که بسيار بسيار حجم لايه Dal رو کاهش ميده، در عوض يه سري دستورات رو در لايه BLL نوشتيم که در کل شايد از تعداد خطوط کدهايي که مي نويسيم کم کنه، اما اگر يه وقت قرار باشه بانک عوض بشه، محبوريم که لايه هاي DAL و BLL رو تغيير بديم که قطعا کار رو شايد کمي زمان بر کنه!

درکل، فکر مي کنم اگر مطمئن هستيم که بانکمون قرار نيست عوض بشه- که شايد خيلي هم کم اتفاق بيوفته - مي تونيم از روشي که esafb52 استفاده ميکنه، استفاده کنيم، هر چند که يک مقدار مفاهيم و تعابير و استاندارد برنامه نويسي 3 لايه رو زير سوال ميبره، اما اگر لازم بود روزي بانک نرم افزارمون عوض بشه، قطعا روش شما کار رو ساده تر خواهد کرد!
موضوع ربطی به تغییر دیتابیس نداره.
در نمونه ای که از دوستمون مثال میزنید در واقع ایشون اومدن لایه Data Access رو با اسم Business Layer نوشتن (دقت کنید کدهای این لایه فقط اجرای دستورات INSERT/UPDATE/DELETE هست یعنی دستورات Data Access و هیچ کدی مربوط به Business در لایه Business وجود نداره)، و فقط صرفا Open و Close لایه Data Access هست که سر جای خودش قرار داره.چون در نمونه ای که ارائه دادن اصلا Business Logic ی لحاظ نشده.
بله، اگه سیستم مورد نظر شما هیچ Business Logic ی نداشته باشه (که به ندرت اینطور هست) شما میتونید به این روش عمل کنید.ولی اگه شما بخواین Business Logic اعمال کنید، با این سیستم یا مجبور هستین Business Logic رو ببرین سمت Application Layer و فرم (همونطور که Data Access یک لایه اومده بالا جای Business Layer) و یا اینکه Business Logic رو هم کنار همون INSERT/UPDATE/DELETE هایی که در این مدل، در Business Layer قرار داده شده بگذارین؛ که در اون صورت شما در لایه Business هم دارین Business Logic رو اعمال میکنید هم Data Access رو!
فرق اون چیزی که من ارائه دادم با طرح دیگه، اینه که کدهای Data Access ی که دوستمون در لایه Business نوشتن رو گذاشتم در لایه Data Access.بقیه چیزی که در Business Layer میبینید، همون Business Logic ی هست که البته بیشترش رو من برای جلوگیری از پیچیدگی حذف کردم.

behnam-soft
پنج شنبه 04 اردیبهشت 1393, 19:40 عصر
پس در واقع منظور شما اینه که من جای لایه ها رو با هم یکم عوض کردم درسته؟
من قسمتی از برنامه ای که دارم به 3 لایه تبدیلش می کنم رو می ذارم اینجا، ممنون می شم در صورت امکان، جای کد ها رو به همون روشی که شما میگی،تغییر بدی، چون به نظرم هیچی بهتر از کد نمی تونه منظور رو منتقل کنه !
قسمتی از لایه DAL:

public int DoAllCommand(SqlCommand cmd)
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = con;
conOpen();
int r = cmd.ExecuteNonQuery();
conClose();
return r;
}

public DataTable AllSelect(SqlDataAdapter da)
{
DataTable dt = new DataTable();
da.SelectCommand.Connection = con;
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.Fill(dt);
return dt;
}
}

قسمتی از لایه BLL:

public class BLL
{
public DataTable ShowAllShahrestan()
{
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = new SqlCommand();
da.SelectCommand.CommandText = "tblShahrestan_ShowShahrestan";
DAL d = new DAL();
return d.AllSelect(da);
}

public int ShahrestanInsert(string ShahrestanName)
{
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "tblShahrestan_insertShahr";
cmd.Parameters.AddWithValue("Shahrestan", ShahrestanName);
DAL d = new DAL();
return d.DoAllCommand(cmd);
}
public int ShahrestanDelete(string ShahrestanId)
{
SqlCommand cmd = new SqlCommand();
cmd.Parameters.AddWithValue("@id", ShahrestanId);
cmd.CommandText = "tblshahrestan_Delete";
DAL d = new DAL();
return d.DoAllCommand(cmd);
}
public DataTable ShowBakhsh(string ShahrestanId)
{
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter();
DAL d = new DAL();
da.SelectCommand = new SqlCommand();
da.SelectCommand.CommandText = "tblBakhsh_ShowBakhsh";
da.SelectCommand.Parameters.AddWithValue("@Shahrestan", ShahrestanId);
return d.AllSelect(da);
}

الان با این تعاریفی که شما کردین من یکم گیج شدم، مگه کار لایه BLL کنترل منطق برنامه نیست ؟ مثلا من می خوام بگم این دیتا تیبلی که برگردوندی، 3 تا از ستون هاش رو با هم جمع کن یا هر کار دیگه ای . . .درست که این مار ها رو در BLL انجام بدیم؟

plus
جمعه 05 اردیبهشت 1393, 11:28 صبح
قراره منطق برنامه در Business Layer قرار بگیره.نه صرفا دستورات INSERT DELETE UPDATE SELECT.برای مثال شما قراره قبل از حذف یک رکورد، بررسی کنید که آیا کاربر جاری اجازه حذف رو داره یا خیر.احتمالا شما میتونید در Business Layer با فراخوانی متدهایی در Data Access Layer، ابتدا سطح دسترسی کاربر جاری رو بدست بیارین. بعد، در صورت مجاز بودن عمل حذف، متدی در Data Access Layer که کارش حذف رکورد هست رو فراخوانی کنید.چیزی که شما گذاشتین باز هم اومدین همون متد هایی که باید در DAL باشن رو در BLL نوشتین.این متدها باید برن توی DAL و از توی BLL فراخوانی بشه.یعنی با این نمونه ای که شما پیاده کردین، توی حالت مد نظر من، DAL شما بزرگتر میشه و BL شما فقط متدهایی هستن که متدهای DAL رو فراخوانی میکنن.یعنی BL خیلی کوچک میشه.ضمن اینکه اگه قراره شما توی BL کد بنویسین وجود آثار Sql (مثل SqlCommand) که مربوط به Data Access هست منطقی نیست.
البته، یک اما ای وجود داره. این که میگین " مثلا من می خوام بگم این دیتا تیبلی که برگردوندی، 3 تا از ستون هاش رو با هم جمع کن یا هر کار دیگه ای . . .درست که این مار ها رو در BLL انجام بدیم؟" کار مجزا سازی DAL از BL همیشه به سادگی مثالی که در مورد عمل حذف زدن زدم نیست.گاهی اوقات، مثل همین مثال ستون ها، ناچار میشید که بخشی از قوانین رو (حالا یا برای Performance بهتر یا پیچیدگی کمتر) توی دستورات SQL اعمال کنید...ولی در این شرایط هم اگه این دستورات در لایه DAL قرار بگیرن (اگر چه شامل بخشی از قوانین کاری هم هستن) معمولا بهتر هست تا بیان داخل BL...
اونچه که مد نظر من هست، برای نمونه شما به این صورته:


class DAL
public int DoAllCommand(SqlCommand cmd)
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = con;
conOpen();
int r = cmd.ExecuteNonQuery();
conClose();
return r;
}

public DataTable AllSelect(SqlDataAdapter da)
{
DataTable dt = new DataTable();
da.SelectCommand.Connection = con;
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.Fill(dt);
return dt;
}

public DataTable ShowAllShahrestan()
{
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = new SqlCommand();
da.SelectCommand.CommandText = "tblShahrestan_ShowShahrestan";
return AllSelect(da);
}

public int ShahrestanInsert(string ShahrestanName)
{
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "tblShahrestan_insertShahr";
cmd.Parameters.AddWithValue("Shahrestan", ShahrestanName);
return DoAllCommand(cmd);
}
public int ShahrestanDelete(string ShahrestanId)
{
SqlCommand cmd = new SqlCommand();
cmd.Parameters.AddWithValue("@id", ShahrestanId);
cmd.CommandText = "tblshahrestan_Delete";
return DoAllCommand(cmd);
}
public DataTable ShowBakhsh(string ShahrestanId)
{
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = new SqlCommand();
da.SelectCommand.CommandText = "tblBakhsh_ShowBakhsh";
da.SelectCommand.Parameters.AddWit hValue("@Shahres tan", ShahrestanId);
return AllSelect(da);
}
}

public class BLL
{
public int ShahrestanInsert(string ShahrestanName)
{
DAL dal = new DAL();
return dal.ShahrestanInsert(ShahrestanName);
}
public int ShahrestanDelete(string ShahrestanId)
{
DAL dal = new DAL();
// You may want to check user permission here...
// if (user cannot delete shahrestan) {
// throw new InvalidOperationException("Access denied.");
// }
return dal.ShahrestanDelete(ShahrestanId);
}
public DataTable ShowBakhsh(string ShahrestanId)
{
DAL dal = new DAL();
return dal.ShowBakhsh(ShahrestanId);
}
}

behnam-soft
یک شنبه 07 اردیبهشت 1393, 13:35 عصر
پس با این حساب، منطقیه که ما زمانی که مثلا به چک کردن شرطی نیاز نداریم، از لایه BLL استفاده نکنیم و مستقیما یه نمونه از DAL بسازیم و آرگومان ها رو پاس بدیم به متد های این لایه ؟؟؟ ضمنا، آیا این مسئله هم منطقیه که ما بیایم در رویداد لود فرم، یه بار از یه لایه دلخواه نمونه بسازیم و در هر قسمتی که نیاز داشتیم، فقط متد های کلاس نمونه سازی شده رو صدا بزنیم ؟؟؟ ببخشید سوالام زیاد شد.

plus
یک شنبه 07 اردیبهشت 1393, 14:18 عصر
پس با این حساب، منطقیه که ما زمانی که مثلا به چک کردن شرطی نیاز نداریم، از لایه BLL استفاده نکنیم و مستقیما یه نمونه از DAL بسازیم و آرگومان ها رو پاس بدیم به متد های این لایه ؟؟؟ ضمنا، آیا این مسئله هم منطقیه که ما بیایم در رویداد لود فرم، یه بار از یه لایه دلخواه نمونه بسازیم و در هر قسمتی که نیاز داشتیم، فقط متد های کلاس نمونه سازی شده رو صدا بزنیم ؟؟؟ ببخشید سوالام زیاد شد.
تا شرط چی باشه.اگه شرط مربوط به قوانین کاری باشه باید در صورت امکان، در Business Layer بررسی بشه نه جای دیگه.در فرم هم، شما باید با لایه Business کار کنید و منطقی نیست که فرم به دو لایه پایینتر (لایه Data Access) دسترسی داشته باشه.