# برنامه نویسی با محصولات مایکروسافت > برنامه نویسی مبتنی بر Microsoft .Net Framework > ASP.NET Web Forms > آموزش: آموزش گام به گام طراحی و پیاده سازی یک فروشگاه اینترنتی مبتنی بر مدل توسعه ی سه لایه در ASP.NET

## clover

در این تاپیک با طراحی و توسعه ی یک فروشگاه اینترنتی بر پایه ی مدل چند لایه در  ASP.NET آشنا خواهید شد. پیش از هر چیز خاطر نشان می کنم که آموزش های ارائه شده در این تاپیک بر پایه ی مطالعه منابع مختلف و تجربیات شخصی من بوده و ممکن است بهترین راه برای پیاده سازی یک فروشگاه اینترنتی بر پایه ی مدل چند لایه نباشد. با این وجود روشی کارآمد است که می توانید در اکثر پروژه های کوچک و متوسطی که قصد انجام آن را دارید به کار گیرید.

در ابتدا شما با مفهوم اولیه ی مدل توسعه ی چند لایه آشنا خواهید شد (در صورتی که با این مفهوم آشنایی دارید می توانید از مطالعه ی آن صرف نظر کنید) و سپس به صورت گام به گام شروع به طراحی و پیاده سازی یک فروشگاه اینترنتی با امکانات ابتدایی، در ASP.NET خواهیم کرد. در ادامه به توسعه ی آن خواهیم پرداخت و امکانات بیشتری به آن خواهیم افزود.

بخش اعظمی از مطالب و کدهای این تاپیک برگرفته از مجموعه مقالاتی است که در وب سایت imar.spaanjaars.com به آموزش ساخت نرم افزار های چند لایه مبتنی بر وب می پردازد. برای مطالعه ی بیشتر می توانید به آدرس های زیر مراجعه کنید:

Building Layered Web Applications with Microsoft ASP.NET 2.0 - Part 1
Building Layered Web Applications with Microsoft ASP.NET 2.0 - Part 2
Building Layered Web Applications with Microsoft ASP.NET 2.0 - Part 3

N-Layered Web Applications with ASP.NET 3.5 Part 1: General Introduction
N-Layered Web Applications with ASP.NET 3.5 Part 2: Introducing the Validation Framework 
N-Layered Web Applications with ASP.NET 3.5 Part 3: Advanced Validation Topics
N-Layered Web Applications with ASP.NET 3.5 Part 4: Sorting, Paging and Filtering
N-Layered Web Applications with ASP.NET 3.5 Part 5: Dealing with Concurrency
N-Layered Web Applications with ASP.NET 3.5 Part 6: Security

----------


## clover

رزرو برای فهرست مطالب

----------


## clover

توسعه ی نرم افزار به صورت لایه ای و یا به عبارت دیگر چند لایه به مدل توسعه ای اشاره دارد که در آن وظایف نرم افزار به بخش های مختلفی از جمله بخش کار با داده ها و پایگاه های داده، بخش منطق برنامه، اعتبار سنجی و امنیت داده ها و بخش نمایش داده ها و رابط کاربری تقسیم بندی شده و کد های مربوط به هر بخش از یک دیگر جدا می شوند. این جداسازی می تواند به صورت منطقی (با استفاده از فضاهای نام) باشد که اصطلاحا به هر بخش یک Layer گفته می شود و یا می تواند به صورت فیزیکی (با استفاده از فایل های مجزا) باشد که در این حالت اصطلاحا به هر بخش یک Tier گفته می شود.

در حالت کلی می توان وظایف یک نرم افزار مبتنی بر دیتابیس  یا Database Driven (نرم افزار هایی که در وب با آن ها سر و کار داریم اغلب از این نوع هستند) را به سه بخش مجزا (سه لایه) تقسیم بندی کنیم:

بخش نمایش داده ها یا Presentation (ارتباط با کاربر یا User Interface)بخش منطق تجاری برنامه (اعتبار سنجی داده ها، امنیت و ...) یا Business Logicبخش دسترسی به داده ها یا Data Access

در برخی مقالات دیتابیس و روال های ذخیره شده ی آن (Stored Procedures) نیز به عنوان لایه ی چهارم در نظر گرفته می شوند که چندان صحیح به نظر نمی رسد.

برای فهم هر چه بهتر مطالب شرح داده شده در بالا، به شکل زیر دقت کنید:

LayersOverviewStart.jpg

در شکل بالا فرآیند کلی نمایش داده های دیتابیس برای کاربر در مدل سه لایه شرح داده شده است. در این مدل، وب سایت نقش لایه ی نمایش یا Presentation را ایفا می کند. لایه ی منطق تجاری برنامه که به صورت مختصر Business Logic Layer) BLL) خوانده می شود، در واقع پلی است بین لایه ی نمایش و لایه ی دسترسی به داده ها که اختصارا Data Access Layer) DAL) خوانده می شود و وظیفه تعامل با دیتابیس و اجرای عملیات چهار گانه ی خواندن، افزودن، ویرایش و حذف داده ها را بر عهده دارد.

یکی از اهداف چنین طراحی این است که ما بتوانیم ساختار هر لایه را به صورت جداگانه تغییر دهیم بدون اینکه نیازی به تغییر ساختار بقیه لایه ها باشد. به طور مثال ممکن است بخواهیم در سیستمی که بر اساس بانک اطلاعاتی MS SQL SERVER ساخته شده است تغییری ایجاد کنیم که بتواند از بانک اطلاعاتی MS Access استفاده کند. در این حالت اگر مدل سه لایه را به خوبی پیاده کرده باشیم می توانیم  تنها با جایگزین کردن لایه ی DAL جدید و بدون دستکاری بقیه لایه ها این کار را انجام دهیم. در حالتی که منظور ما از لایه، لایه ی فیزیکی (Tier) باشد، این کار به سادگی تعویض یک فایل DLL خواهد بود.

در دیاگرام بالا شما شاهد فرآیندی هستید که طی 6 مرحله اتفاق می افتد:

لایه ی Presentation از لایه ی Business Logic تقاضای داده هایی را می کند.لایه ی Business Logic در صورت نیاز بررسی هایی را بر روی این درخواست انجام داده (به طور مثال اینکه آیا کاربر جاری اجازه دسترسی به داده های درخواست شده را دارد یا نه) و در صورت معتبر بودن، درخواستی را برای دریافت داده های مورد نظر به لایه ی Data Access ارسال می کند.لایه ی Data Access به دیتابیس متصل شده و به دنبال رکورد یا رکورد های درخواست شده می گردد.در صورت وجود، رکورد یا رکورد های مورد نظر به لایه Data Access برگردانده می شوند.لایه ی Data Access این رکورد یا رکوردها را در قالب یک شی یا لیستی از اشیا به لایه ی Business Logic ارسال می کند. این اشیا که غالبا Business Objects یا Business Entities نامیده می شوند، در واقع ابزاری برای تبادل داده ها در بین لایه های مختلف هستند.در نهایت لایه ی Business Logic داده ها را به لایه ی Presentation باز می گرداند. جایی که می توانند از طریق یک صفحه ی وب به کاربر نمایش داده شوند.

----------


## clover

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

در این آموزش ما قصد داریم یک فروشگاه اینترنتی را بر پایه ی مدل توسعه ی  سه لایه و در محیط ASP.NET طراحی و ایجاد کنیم. سیستم مدیریت پایگاه داده ی  مورد استفاده در این پروژه MS SQL SERVER بوده و برای ارتباط با پایگاه  داده از ADO.NET استفاده خواهیم کرد. در این راه از مدل فرآیندی شبیه به  مدل افزایشی استفاده خواهیم کرد. با این حال به دلیل اینکه این آموزش بیشتر  بر پیاده سازی فروشگاه اینترنتی مورد نظر تاکید دارد، از جزییات مربوط به  تحلیل، مدل سازی و تا حدودی هم طراحی صرف نظر شده است و فقط تا آن اندازه  که نیاز بوده است به آن ها پرداخته شده است.

*نیازمندی های کاربران*
پیش از هر چیز باید نیازمندی های کاربران یک وب سایت فروشگاه اینترنتی را  شناسایی کنیم. به دلیل تغییر نیازمندی ها در طول زمان و افزوده شدن  نیازمندی های جدید، این کار در طول پروژه ممکن است چندین بار تکرار شود.
با توجه به این که این یک تاپیک آموزشی بوده و شخص یا شرکت خاصی این سیستم  را سفارش نداده است نیازمندی های کلی کاربران یک فروشگاه اینترنتی را در  نظر گرفته و به اختیار بعضی از آنها را در این مرحله از کار برای شروع  انتخاب خواهیم کرد:

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

*مدل سازی*
همانطور که پیشتر گفته شد در این پروژه از مدل فرآیندی شبیه به مدل فرآیند  افزایشی استفاده خواهیم کرد. در این مدل فرآیند در ابتدا فروشگاه اینترنتی  خواهیم ساخت که به نیازمندی اصلی کاربران یعنی امکان مدیریت محصولات برای  مدیران و نمایش محصولات به مشتریان خواهد پرداخت.

در این حالت نمودار ER ما فقط یک موجودیت به نام Product خواهد داشت که دارای صفات خاصه ی زیر است:

*Id*: شناسه ی محصول
*Name*: نام محصول
*Title*: عنوان صفحه ای که محصول در آن نمایش داده خواهد شد
*MetaDescription*: توضیحات متای صفحه ای که محصول در آن نمایش داده خواهد شد
*MetaKeywords*: کلمات کلیدی متای صفحه ای که محصول در آن نمایش داده خواهد شد
*Content*: محتوای صفحه ای که محصول در آن نمایش داده خواهد شد
*Price*: قیمت محصول
*Weight*: وزن محصول
*SerialNumber*: شماره سریال محصول
*CreateDate*: تاریخ افزودن محصول به فروشگاه

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

----------


## clover

در این پروژه از پایگاه داده ی پیش فرضی که توسط ASP.NET Configuration در  پوشه ی App_Data ایجاد خواهد شد استفاده نخواهیم کرد بلکه به صورت دستی  نسبت به ایجاد و آماده سازی پایگاه داده مورد نظر برای استفاده در پروژه  اقدام خواهیم کرد.

معمولا همراه با نصب ویژوال استودیو یک نسخه ی آزمایشی و رایگان از MS SQL  Server با پسوند Express بر روی سیستم شما نصب می شود. در صورتی که در  هنگام نصب ویژوال استودیو تیک مربوط به نصب MS SQL Server Express را  برداشته اید می توانید از طریق نصاب ویژوال استودیو آن را نصب نمایید. ما  قصد داریم بانک اطلاعاتی مورد نظر خود را با استفاده از ابزار Server  Explorer موجود در ویژوال استودیو بر روی این نصب از MS SQL Server ایجاد  نماییم.

تذکر: در این تاپیک از نسخه ی 2012 نرم افزار ویژوال  استودیو استفاده خواهیم کرد. در صورتی که از نسخه های قدیمی تر ویژوال  استودیو استفاده می کنید ممکن است نیاز داشته باشید در مطالب گفته شده کمی  تغییر ایجاد نمایید. 

ویژوال استودیو را باز کرده و از پنجره ی Server Explorer بر روی گزینه ی  Data Connections کلیک راست کرده و از منوی ظاهر شده گزینه ی Create New  SQL Server Database را انتخاب کنید.

005.png 
در پنجره ی ظاهر شده در قسمت Server name مقدار sqlexpress\. که همان آدرس  سرور MS SQL Server Express است را وارد نمایید. همچنین در قسمت New  database name مقدار db_eShop را وارد نمایید. این نام پایگاه داده ای است  که برای این پروژه قصد ایجاد آن را داریم. 

006.png 
سپس بر روی دکمه ی OK کلیک کنید تا پایگاه داده ی مورد نظر ما ایجاد شده و  به لیست پایگاه های داده ی موجود در پنجره ی Server Explorer اضافه شود.

007.png 
بر روی مثلث کوچک کنار نام دیتابیس کلیک کرده تا زیر شاخه های دیتابیس ظاهر  شود. سپس بر روی شاخه ی Tables کلیک راست کرده و گزینه ی Add New Table را  انتخاب نمایید.

008.png 
در پنجره ی ظاهر شده فیلد های مورد نظر را مطابق شکل زیر وارد کرده و سپس  جدول مورد نظر را با نام eshop_Products ذخیره کنید. دقت کنید که فیلد Id  کلید اصلی این جدول می باشد. همچنین فیلد CreateDate مقدار پیش فرض خود را  از تابع ()getdate دریافت می نماید.

009.png 
حال نوبت به ایجاد روال های ذخیره شده (Stored Procedures) می رسد. در این  قسمت پنج روال ذخیره شده زیر را برای انجام عملیات انتخاب لیست محصولات،  انتخاب یک محصول خاص و ایجاد، ویرایش و حذف یک محصول خاص، ایجاد خواهیم  کرد. برای این منظور بر روی شاخه ی Stored Procedures کلیک راست کرده و  گزینه ی Add New Stored Procedure را انتخاب کنید. 

010.png 
در پنجره ی ظاهر شده دستورات زیر را وارد کرده و دکمه ی Update (در نسخه  های قدیمی تر دکمه ی Execute) را کلیک کنید تا روال ذخیره شده ی مورد نظر  ایجاد شود.

روال ذخیره شده ی انتخاب لیست محصولات:
CREATE PROCEDURE [dbo].[eshop_Products_SelectAll]
AS
    SELECT    Id,
            Name,
            Title,
            MetaDescription,
            MetaKeywords,
            Content,
            Price,
            [Weight],
            SerialNumber,
            CreateDate

    FROM    dbo.eshop_Products

    ORDER BY CreateDate DESC
RETURN 0
برای چهار روال دیگر نیز به همین شکل عمل کرده و دستورات زیر را وارد کنید.

روال ذخیره شده ی انتخاب محصول:
CREATE PROCEDURE [dbo].[eshop_Products_SelectItem]
    @Id    UNIQUEIDENTIFIER
AS
    SELECT    Id,
            Name,
            Title,
            MetaDescription,
            MetaKeywords,
            Content,
            Price,
            [Weight],
            SerialNumber,
            CreateDate

    FROM    dbo.eshop_Products

    WHERE    Id = @Id
RETURN 0
روال ذخیره شده ی افزودن محصول:
CREATE PROCEDURE [dbo].[eshop_Products_InsertItem]
    @Id                    UNIQUEIDENTIFIER,
    @Name                NVARCHAR(50),
    @Title                NVARCHAR(50),
    @MetaDescription    NVARCHAR(300),
    @MetaKeywords        NVARCHAR(800),
    @Content            NVARCHAR(MAX),
    @Price                MONEY,
    @Weight                INT,
    @SerialNumber        NVARCHAR(50)

AS
    INSERT dbo.eshop_Products
    (
        Id,
        Name,
        Title,
        MetaDescription,
        MetaKeywords,
        Content,
        Price,
        [Weight],
        SerialNumber
    )
    VALUES
    (
        @Id,
        @Name,
        @Title,
        @MetaDescription,
        @MetaKeywords,
        @Content,
        @Price,
        @Weight,
        @SerialNumber
    )
RETURN 0

روال ذخیره شده ی ویرایش محصول:
CREATE PROCEDURE [dbo].[eshop_Products_UpdateItem]
    @Id                    UNIQUEIDENTIFIER,
    @Name                NVARCHAR(50),
    @Title                NVARCHAR(50),
    @MetaDescription    NVARCHAR(300),
    @MetaKeywords        NVARCHAR(800),
    @Content            NVARCHAR(MAX),
    @Price                MONEY,
    @Weight                INT,
    @SerialNumber        NVARCHAR(50)

AS
    UPDATE    dbo.eshop_Products

    SET        Id = @Id,
            Name = @Name,
            Title = @Title,
            MetaDescription = @MetaDescription,
            MetaKeywords = @MetaKeywords,
            Content = @Content,
            Price = @Price,
            [Weight] = @Weight,
            SerialNumber = @SerialNumber

    WHERE    Id = @Id
RETURN 0
روال ذخیره شده ی حذف محصول:
CREATE PROCEDURE [dbo].[eshop_Products_DeleteItem]
    @Id    UNIQUEIDENTIFIER

AS
    DELETE    dbo.eshop_Products
    WHERE    Id = @Id
RETURN 0

----------


## clover

موجودیت های داده ای به زبان ساده کلاس هایی هستند که از اشیا ساخته شده از  آن ها برای ارسال داده ها در بین لایه های مختلف نرم افزار استفاده می  شود. در حقیقت داده هایی که باید بین لایه های مختلف جا به جا شوند در قالب  اشیایی از این کلاس ها بسته بندی می شوند. به طور مثال داده های مربوط به  یک محصول که در لایه ی Presentation از طریق وب فرم ها برای ذخیره در  پایگاه داده از کاربر دریافت می شوند در قالب یک شی از نوع Product به لایه  ی Business Logic ارسال می شوند.

این موجودیت ها، برای نظم و خوانایی بیشتر نرم افزار اغلب در یک فضای نام جداگانه یا حتی در یک پروژه ی جداگانه تعریف می شوند.

در اولین قدم در ویژوال استودیو یک Solution ایجاد خواهیم کرد. این  Solution در ادامه برای نگهداری کلیه پروژه های مورد نیاز و همچنین وب سایت  فروشگاه اینترنتی مورد استفاده قرار خواهد گرفت.
ویژوال استودیو را باز کرده و از منوی File گزینه ی New Project را انتخاب کنید.

011.png
در پنجره ی ظاهر شده مطابق شکل زیر زبان برنامه نویسی را #C و نوع پروژه را  Class Library انتخاب کنید. در قسمت Name مقدار BusinessEntities را وارد  کرده و در قسمت Solution name مقدار eShop را وارد نمایید. سپس بر روی دکمه  ی OK کلیک کنید تا Solution و همچنین پروژه ی مورد نظر ایجاد شود.

012.png
پس از ایجاد Solution پنجره ی Solution Explorer  شما باید مانند شکل زیر باشد:

013.png
بر روی پروژه ی BusinessEntities کلیک راست کرده و گزینه ی Properties را  انتخاب نمایید. در پنجره ی ظاهر شده در تب Application در قسمت Default  namespace مقدار eShop.BusinessEntities را وارد کرده و بر روی دکمه ی Save  کلیک نمایید.

در ابتدا کلاس پیشفرضی که همراه با پروژه ی BusinessEntities و با نام  Class1.cs ایجاد شده است را حذف خواهیم کرد. سپس اولین Business Entity خود  را با نام Product ایجاد خواهیم کرد. در حال حاضر فقط به همین یک موجودیت  نیاز خواهیم داشت.

بر روی Class1.cs کلیک راست کرده و گزینه ی Delete را انتخاب نمایید و در  پنجره ی ظاهر شده گزینه ی OK را کلیک کنید. سپس بر روی پروژه ی  BusinessEntities کلیک راست کرده و از بخش Add گزینه ی New Item را انتخاب  نمایید.

014.png
در پنجره ی ظاهر شده نوع فایل را Class انتخاب کرده و نام آن را Product  قرار دهید و بر روی گزینه ی Add کلیک کنید سپس کد های کلاس Product را به  شکل زیر ویرایش کنید:
using System;
using System.ComponentModel;

namespace eShop.BusinessEntities
{
    [DataObject]
    public class Product
    {
        [DataObjectField(true, false, false)]
        public Guid Id { get; set; }

        [DataObjectField(false, false, false)]
        public string Name { get; set; }

        [DataObjectField(false, false, false)]
        public string Title { get; set; }

        [DataObjectField(false, false, true)]
        public string MetaDescription { get; set; }

        [DataObjectField(false, false, true)]
        public string MetaKeywords { get; set; }

        [DataObjectField(false, false, true)]
        public string Content { get; set; }

        [DataObjectField(false, false, false)]
        public decimal Price { get; set; }

        [DataObjectField(false, false, false)]
        public int Weight { get; set; }

        [DataObjectField(false, false, false)]
        public string SerialNumber { get; set; }

        [DataObjectField(false, false, false)]
        public DateTime CreateDate { get; set; }
    }
}

----------


## clover

در این مرحله یک پروژه ی دیگر از نوع Class Library برای نگهداری کلاس های لایه ی Data Access نرم افزار خود ایجاد خواهیم کرد.

از پنجره Solution Explore بر روی Solution خود راست کلیک کرده و از بخش Add گزینه ی New Project را انتخاب کنید.

016.png

در پنجره ی ظاهر شده نوع پروژه را Class Library و نام آن را DataAccess بگذارید. پس از ایجاد پروژه، از قسمت Properties، فضای نام پیشفرض پروژه را به eShop.DataAccess تغییر دهید. سپس فایل Class1.cs را حذف کنید.

از آنجایی که این پروژه در واقع نقش لایه Data Access را ایفا می کند نیاز داریم به بانک اطلاعاتی دسترسی داشته باشیم. بنابر این به یک Connection String نیاز خواهیم داشت. با این حال اگر بخواهیم آن را مستقیما در این پروژه تعریف کنیم در صورتی که نیاز به تغییر آن داشته باشیم باید مجددا پروژه را کامپایل کرده و خروجی بگیریم. برای انعطاف بیشتر، Connection String مورد نظر را از طریق کلاس ConfigurationManager دریافت خواهیم کرد. این کلاس امکان دسترسی به تنظیمات نرم افزار را برای ما فراهم می کند. در وب سایت ها این تنظیمات در فایل هایی با پسوند config قرار می گیرند. در واقع ما از Connection String تعریف شده در فایل Web.config استفاده خواهیم کرد و از آنجایی که ممکن است چند Connection String در این فایل تعریف شده باشد نام آن را در یک Property با نام ConnectionStringName در App Settings که در همان فایل Web.config قرار دارد نگهداری خواهیم کرد. در هنگام ایجاد وب سایت در این مورد بیشتر توضیح داده خواهد شد.
با توجه به توضیحات بالا پیش از هر چیز برای دسترسی به کلاس ConfigurationManager باید یک ارجاع به اسمبلی System.Configuration بدهیم. برای این منظور بر روی پروژه ی DataAccess کلیک راست کرده و گزینه ی Add Reference را انتخاب کنید.

017.png

در پنجره ی ظاهر شده از قسمت Assemblies بر روی گزینه ی Framework کلیک کرده و از لیست ظاهر شده System.Configuration را انتخاب کرده و دکمه ی OK را کلیک نمایید.

019.png

سپس یک کلاس جدید با نام AppConfiguration ایجاد کرده و محتویات آن را به این شکل تغییر دهید:
using System;
using System.Configuration;

namespace eShop.DataAccess
{
    public static class AppConfiguration
    {
        public static string ConnectionString
        {
            get
            {
                return ConfigurationManager.ConnectionStrings[AppConfiguration.ConnectionStringName].ConnectionString;
            }
        }
        public static string ConnectionStringName
        {
            get
            {
                return ConfigurationManager.AppSettings["ConnectionStringName"];
            }
        }
    }
}        
حال نوبت به ایجاد کلاس ProductRepository می رسد. این کلاس وظیفه ارتباط با دیتابیس برای انجام عملیات مرتبط با محصولات را بر عهده دارد. این عملیات شامل گرفتن لیست محصولات، گرفتن یک محصول خاص و اضافه، ویرایش و یا حذف یک محصول خاص می باشد. برای هر کدام از عملیات نام برده شده یک تابع در این کلاس تعریف خواهیم کرد. همچنین توابع دیگری نیز برای انجام عملیات داخلی کلاس تعریف خواهیم کرد. از آنجایی که ورودی یا خروجی های این توابع معمولا موجودیت های داده ای ما می باشند باید یک ارجاع به پروژه ای که این موجودیت ها در آن تعریف شده اند (پروژه ی BusinessEntities) بدهیم تا بتوانیم از آنها دراین پروژه استفاده کنیم. مجددا از گزینه ی Add Reference استفاده کرده و در پنجره ی ظاهر شده این بار از قسمت Solution بر روی Projects کلیک کرده و از لیست ظاهر شده پروژه ی BusinessEntities را تیک زده و دکمه ی OK را کلیک کنید.

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

کلاس ProductRepository را ایجاد کرده و محتویات آن را به این شکل ویرایش کنید:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;

using eShop.BusinessEntities;

namespace eShop.DataAccess
{
    public static class ProductRepository
    {
        public static List<Product> GetList()
        {
            List<Product> products = new List<Product>();

            using (SqlConnection sqlConnection = new SqlConnection(AppConfiguration.ConnectionString))
            {
                SqlCommand sqlCommand = new SqlCommand("eshop_Products_SelectAll", sqlConnection);
                sqlCommand.CommandType = CommandType.StoredProcedure;

                sqlConnection.Open();
                using (SqlDataReader sqlDataReader = sqlCommand.ExecuteReader())
                {
                    if (sqlDataReader.HasRows)
                        while (sqlDataReader.Read())
                            products.Add(GedDataRecod(sqlDataReader));

                    sqlDataReader.Close();
                }
                sqlConnection.Close();
            }

            return products;
        }
        public static Product GetItem(Guid id)
        {
            Product product = null;

            using (SqlConnection sqlConnection = new SqlConnection(AppConfiguration.ConnectionString))
            {
                SqlCommand sqlCommand = new SqlCommand("eshop_Products_SelectItem", sqlConnection);
                sqlCommand.CommandType = CommandType.StoredProcedure;

                sqlConnection.Open();
                using (SqlDataReader sqlDataReader = sqlCommand.ExecuteReader())
                {
                    if (sqlDataReader.HasRows && sqlDataReader.Read())
                        product = GedDataRecod(sqlDataReader);

                    sqlDataReader.Close();
                }
                sqlConnection.Close();
            }

            return product;
        }
        public static void AddItem(Product product)
        {
            using (SqlConnection sqlConnection = new SqlConnection(AppConfiguration.ConnectionString))
            {
                SqlCommand sqlCommand = new SqlCommand("eshop_Products_InsertItem", sqlConnection);
                sqlCommand.CommandType = CommandType.StoredProcedure;

                FillSqlParameters(product, sqlCommand.Parameters);

                sqlConnection.Open();
                sqlCommand.ExecuteNonQuery();
                sqlConnection.Close();
            }
        }
        public static void UpdateItem(Product product)
        {
            using (SqlConnection sqlConnection = new SqlConnection(AppConfiguration.ConnectionString))
            {
                SqlCommand sqlCommand = new SqlCommand("eshop_Products_UpdateItem", sqlConnection);
                sqlCommand.CommandType = CommandType.StoredProcedure;

                FillSqlParameters(product, sqlCommand.Parameters);

                sqlConnection.Open();
                sqlCommand.ExecuteNonQuery();
                sqlConnection.Close();
            }
        }
        public static void DeleteItem(Product product)
        {
            using (SqlConnection sqlConnection = new SqlConnection(AppConfiguration.ConnectionString))
            {
                SqlCommand sqlCommand = new SqlCommand("eshop_Products_DeleteItem", sqlConnection);
                sqlCommand.CommandType = CommandType.StoredProcedure;

                sqlCommand.Parameters.AddWithValue("@Id", product.Id);

                sqlConnection.Open();
                sqlCommand.ExecuteNonQuery();
                sqlConnection.Close();
            }
        }
        private static Product GedDataRecod(IDataRecord dataRecord)
        {
            Product product = new Product();

            for (int i = 0; i < dataRecord.FieldCount; i++)
            {
                string fieldName = dataRecord.GetName(i);

                switch (fieldName)
                {
                    case "Id":
                        product.Id = dataRecord.GetGuid(i);
                        break;
                    case "Name":
                        product.Name = dataRecord.GetString(i);
                        break;
                    case "Title":
                        product.Title = dataRecord.GetString(i);
                        break;
                    case "MetaDescription":
                        product.MetaDescription = dataRecord.GetString(i);
                        break;
                    case "MetaKeywords":
                        product.MetaKeywords = dataRecord.GetString(i);
                        break;
                    case "Content":
                        product.Content = dataRecord.GetString(i);
                        break;
                    case "Price":
                        product.Price = dataRecord.GetDecimal(i);
                        break;
                    case "Weight":
                        product.Weight = dataRecord.GetInt32(i);
                        break;
                    case "SerialNumber":
                        product.SerialNumber = dataRecord.GetString(i);
                        break;
                    case "CreateDate":
                        product.CreateDate = dataRecord.GetDateTime(i);
                        break;
                }
            }

            return product;
        }
        private static void FillSqlParameters(Product product, SqlParameterCollection sqlParameters)
        {
            sqlParameters.AddWithValue("@Id", product.Id);
            sqlParameters.AddWithValue("@Name", product.Name);
            sqlParameters.AddWithValue("@Title", product.Title);
            sqlParameters.AddWithValue("@MetaDescription", product.MetaDescription);
            sqlParameters.AddWithValue("@MetaKeywords", product.MetaKeywords);
            sqlParameters.AddWithValue("@Content", product.Content);
            sqlParameters.AddWithValue("@Price", product.Price);
            sqlParameters.AddWithValue("@Weight", product.Weight);
            sqlParameters.AddWithValue("@SerialNumber", product.SerialNumber);
        }
    }
}

----------


## clover

یک پروژه ی دیگر از نوع Class Library و با نام BusinessLogic به Solution خود اضافه کنید. سپس فضای نام پیش فرض آن را به eShop.BusinessLogic تغییر داده و کلاس پیش فرض ایجاد شده همراه با پروژه را نیز حذف کنید.
این پروژه در واقع نقش لایه ی Business Logic ما را ایفا خواهد کرد. همانطور که پیش تر گفته شد این لایه در واقع مانند یک پل بین لایه های Presentation و  Data Access عمل خواهد کرد. این لایه وظیفه ی بررسی درخواست هایی را دارد که از لایه ی Presentation به آن ارسال می شوند. در صورتی که این درخواست ها معتبر باشند به لایه ی Data Access فرستاده شده و نتیجه به لایه Presentation برگردانده می شود.

از آنجایی که در این لایه نیاز به دسترسی به لایه های Business Entities و Data Access را داریم پیش از هر چیز ارجاع هایی به پروژه های BusinessEntities و DataAccess ایجاد نمایید. همچنین برای دسترسی به درخواست HTTP کاربران و همچنین سیستم Membership، ارجاع هایی به اسمبلی های System.Web و System.Security ایجاد نمایید.

فرض کنید قصد داریم یک محصول را به فروشگاه اضافه کنیم. درخواست ثبت این محصول از لایه ی Presentation و به شکل فراخوانی یک متد و ارسال مشخصات محصول مورد نظر در قالب یک شی از نوع Product به لایه ی Business Logic ارسال می شود. در این لایه بررسی بر روی فیلد ها انجام شده و مشخص می شود که فیلد SerialNumber شی مورد نظر خالی می باشد. در این حالت از ارسال درخواست به لایه ی Data Access و ثبت محصول جلوگیری به عمل می آید. با این وجود نیاز خواهیم داشته مشکل به وجود آمده را به لایه ی Presentation گزارش دهیم. برای این منظور کلاسی تعریف خواهیم کرد که شامل نتیجه ی عملیات مورد نظر (خطا یا موفقیت) و همچنین یک پیغام می باشد.

پیش از ایجاد این کلاس به ایجاد انواع داده ای که در این کلاس مورد استفاده قرار خواهند گرفت خواهیم پرداخت. اولین نوع داده ای که به آن نیاز داریم، یک نوع داده ای شمارشی (Enum)  با نام OperationStatus برای مشخص کردن وضعیت عملیات می باشد. این نوع داده ای در پروژه ی BusinessLogic تعریف خواهد شد.

یک کلاس جدید با نام OperationStatus به پروژه ی BusinessLogic اضافه کرده و محتویات آن را به این شکل ویرایش کنید:
namespace BusinessLogic
{
    public enum OperationStatus
    {
        Success,
        SuccessWithError,
        Error
    }
}
نوع داده ای دیگری که ایجاد خواهیم کرد یک کلاس با نام Message می باشد. از آنجایی که در آینده این کلاس را در وب سایت و برای انتقال و نمایش پیغام های مختلف مورد استفاده قرار خواهیم داد آن را خارج از پروژه ی BusinessLogic و در یک پروژه ی مجزا با نام CommonLibrary تعریف خواهیم کرد. سپس از پروژه ی BusinessLogic یک ارجاع به آن ایجاد خواهیم کرد.

یک پروژه ی جدید به نام CommonLibrary ایجاد کرده و فضای نام پیش فرض آن را به eShop.CommonLibrary تغییر دهید.

یک کلاس جدید با نام MessageType در این پروژه ایجاد کرده و محتویات آن را به این شکل ویرایش کنید:
namespace eShop.CommonLibrary
{
    public enum MessageType
    {
        Info,
        Warning,
        Success,
        Error
    }
}
این کلاس حاوی تعریف یک نوع شمارشی جدید به نام MessageType می باشد که در کلاس Message برای مشخص کردن نوع پیام استفاده خواهد شد.

حال نوبت به ایجاد کلاس Message می رسد. این کلاس حاوی دو Property می باشد. یکی از نوع string که برای نگهداری متن پیام مورد استفاده قرار می گیرد و دیگری از نوع MessageType که برای مشخص کردن نوع پیام مورد نظر مورد استفاده قرار خواهد گرفت. در آینده خواهید دید که چگونه از این کلاس برای انتقال پیام ها از لایه ی BusinessLogic به وب سایت و نمایش آن در صفحات استفاده خواهیم کرد.

یک کلاس جدید با نام Message به پروژه ی CommonLibrary اضافه کرده و محتویات آن را به این شکل ویرایش کنید:
using System;

namespace eShop.CommonLibrary
{
    public class Message
    {
        public string Text { get; set; }
        public MessageType Type { get; set; }
    }
}
حال قادر خواهیم بود کلاس OperationResult را ایجاد نماییم. این کلاس حاوی دو Property می باشد. یکی از نوع OperationStatus که برای مشخص کردن نتیجه عملیات مورد استفاده قرار می گیرد و دیگری از نوع Message می باشد که پیغامی متنی و قابل فهم برای کاربر را در خود نگهداری خواهد کرد.

در پروژه ی BusinessLogic یک ارجاع به پروژه ی CommonLibrary ایجاد کنید سپس یک کلاس جدید با نام OperationResult به پروژه اضافه کرده و محتوای آن را به این شکل ویرایش کنید:
using System;

using eShop.CommonLibrary;

namespace BusinessLogic
{
    public class OperationResult
    {
        public Message Message { get; set; }
        public OperationStatus Status { get; set; }
    }
}
حال نوبت به ایجاد بخش اصلی در این لایه می رسد. این بخش کلاسی با نام ProductManager می باشد که همانطور که از نام آن پیداست وظیفه ی مدیریت درخواست های مربوط به محصولات فروشگاه را بر عهده دارد. این در خواست ها توسط توابعی که در این کلاس تعریف خواهیم کرد قابل انجام می باشند. همانند کلاس ProductRepository و همانطور که قبلا نیز ذکر شد از آنجایی که نیاز به ایجاد نمونه هایی از این کلاس ها نخواهیم داشت، کلاس و کلیه ی توابع موجود در آن را از نوع static تعریف خواهیم کرد.

یک کلاس جدید با نام ProductManager ایجاد نموده و محتویات آن را به این شکل ویرایش نمایید:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web;
using System.Web.Security;

using eShop.BusinessEntities;
using eShop.CommonLibrary;
using eShop.DataAccess;


namespace BusinessLogic
{
    [DataObject]
    public class ProductManeger
    {
        [DataObjectMethod(DataObjectMethodType.Select, true)]
        public static List<Product> GetList()
        {
            return ProductRepository.GetList();
        }

        [DataObjectMethod(DataObjectMethodType.Select)]
        public static Product GetItem(Guid id)
        {
            return ProductRepository.GetItem(id);
        }

        [DataObjectMethod(DataObjectMethodType.Insert, true)]
        public static OperationResult AddItem(Product product)
        {
            OperationResult result = new OperationResult();
            result.Status = OperationStatus.Error;

            if (!HttpContext.Current.User.IsInRole("Administrator  "))
            {
                result.Message = new Message { Type = MessageType.Error, Text = "اجازه ی انجام چنین عملیاتی وجود ندارد" };
                return result;
            }

            if (!ValidateProduct(product, out result))
                return result;

            List<Product> products = GetList();

            if (products.Exists(x => x.Id == product.Id))
            {
                result.Message = new Message { Type = MessageType.Warning, Text = "محصولی با این شناسه از قبل وجود دارد" };
                return result;
            }

            if (products.Exists(x => x.Name == product.Name))
            {
                result.Message = new Message { Type = MessageType.Warning, Text = "محصولی با این نام از قبل وجود دارد" };
                return result;
            }

            if (products.Exists(x => x.Title == product.Title))
            {
                result.Message = new Message { Type = MessageType.Warning, Text = "محصولی با این عنوان از قبل وجود دارد" };
                return result;
            }

            ProductRepository.AddItem(product);

            result.Status = OperationStatus.Success;
            result.Message = new Message { Type = MessageType.Success, Text = "محصول مورد نظر با موفقیت اضافه گردید" };

            return result;
        }

        [DataObjectMethod(DataObjectMethodType.Update, true)]
        public static OperationResult EditItem(Product product)
        {
            OperationResult result = new OperationResult();
            result.Status = OperationStatus.Error;

            if (!HttpContext.Current.User.IsInRole("Administrator  "))
            {
                result.Message = new Message { Type = MessageType.Error, Text = "اجازه ی انجام چنین عملیاتی وجود ندارد" };
                return result;
            }

            if (!ValidateProduct(product, out result))
                return result;

            List<Product> products = GetList();

            if (!products.Exists(x => x.Id == product.Id))
            {
                result.Message = new Message { Type = MessageType.Warning, Text = "محصولی با این شناسه یافت نشد" };
                return result;
            }

            if (products.Exists(x => x.Name == product.Name && x.Id != product.Id))
            {
                result.Message = new Message { Type = MessageType.Warning, Text = "محصولی با این نام از قبل وجود دارد" };
                return result;
            }

            if (products.Exists(x => x.Title == product.Title && x.Id != product.Id))
            {
                result.Message = new Message { Type = MessageType.Warning, Text = "محصولی با این عنوان از قبل وجود دارد" };
                return result;
            }

            ProductRepository.UpdateItem(product);

            result.Status = OperationStatus.Success;
            result.Message = new Message { Type = MessageType.Success, Text = "محصول مورد نظر با موفقیت ویرایش گردید" };

            return result;
        }

        [DataObjectMethod(DataObjectMethodType.Delete, true)]
        public static OperationResult DeleteItem(Product product)
        {
            OperationResult result = new OperationResult();
            result.Status = OperationStatus.Error;


            if (!HttpContext.Current.User.IsInRole("Administrator  "))
            {
                result.Message = new Message { Type = MessageType.Error, Text = "اجازه ی انجام چنین عملیاتی وجود ندارد" };
                return result;
            }

            List<Product> products = GetList();

            if (!products.Exists(x => x.Id == product.Id))
            {
                result.Message = new Message { Type = MessageType.Warning, Text = "محصولی با این شناسه یافت نشد" };
                return result;
            }

            ProductRepository.DeleteItem(product);

            result.Status = OperationStatus.Success;
            result.Message = new Message { Type = MessageType.Success, Text = "محصول مورد نظر با موفقیت حذف گردید" };

            return result;
        }

        private static bool ValidateProduct(Product product, out OperationResult result)
        {
            result = new OperationResult();
            result.Status = OperationStatus.Error;
            result.Message = new Message { Type = MessageType.Error };

            product.Name = product.Name.Trim();
            product.Title = product.Title.Trim();
            product.MetaDescription = product.MetaDescription.Trim();
            product.MetaKeywords = product.MetaKeywords.Trim();
            product.Content = product.Content.Trim();
            product.SerialNumber = product.SerialNumber.Trim();

            if (string.IsNullOrEmpty(product.Name))
            {
                result.Message.Text = "نام محصول نمی تواند خالی باشد";
                return false;
            }

            if (product.Name.Length > 50)
            {
                result.Message.Text = "نام محصول نمی تواند بیشتر از 50 حرف باشد";
                return false;
            }

            if (string.IsNullOrEmpty(product.Title))
            {
                result.Message.Text = "عنوان محصول نمی تواند خالی باشد";
                return false;
            }

            if (product.Title.Length > 50)
            {
                result.Message.Text = "عنوان محصول نمی تواند بیشتر از 50 حرف باشد";
                return false;
            }

            if (product.MetaDescription.Length > 300)
            {
                result.Message.Text = "توضیحات محصول نمی تواند بیشتر از 300 حرف باشد";
                return false;
            }

            if (product.MetaKeywords.Length > 300)
            {
                result.Message.Text = "کلمات کلیدی محصول نمی تواند بیشتر از 800 حرف باشد";
                return false;
            }

            if (product.Content.Length > 10000)
            {
                result.Message.Text = "شرح محصول نمی تواند بیشتر از 10000 حرف باشد";
                return false;
            }

            if (product.Price < 0)
            {
                result.Message.Text = "قیمت وارد شده نامعتبر است";
                return false;
            }

            if (product.Weight < 0)
            {
                result.Message.Text = "وزن وارد شده نامعتبر است";
                return false;
            }

            if (string.IsNullOrEmpty(product.SerialNumber))
            {
                result.Message.Text = "شماره سریال محصول نمی تواند خالی باشد";
                return false;
            }

            if (product.SerialNumber.Length > 50)
            {
                result.Message.Text = "شماره سریال محصول نمی تواند بیشتر از 50 حرف باشد";
                return false;
            }

            return true;
        }
    }
}

----------


## clover

حال نوبت به ایجاد لایه ی Presentation که در واقع همان وب سایت مورد نظر ما می باشد رسیده است.

از پنجره Solution Explore بر روی Solution خود راست کلیک کرده و از بخش Add گزینه ی New Web Site را انتخاب کنید.

020.png
در پنجره ی ظاهر شده از بخش Visual C#‎‎‎‎ نوع وب سایت را ASP.NET Empty Web Site انتخاب کرده و مسیر آن را در همان پوشه ای که Solution ما در آن قرار دارد و در پوشه WebSite انتخاب کنید (نیازی به ساخت این پوشه نیست. فقط کافیست به انتهای مسیر Solution مقدار Website\ را نیز اضافه کنید تا در هنگام ایجاد وب سایت این پوشه به صورت خودکار ایجاد شود). سپس بر روی دکمه ی OK کلیک کنید تا وب سایت نظر ایجاد شود.

021.png
در این لایه نیاز داریم به موجودیت های داده ای دسترسی داشته باشیم. از طرف دیگر دسترسی هایی را نیز به توابع موجود در لایه ی Business Logic و کلاس های تعریف شده در فضای نام CommonLibrary نیاز خواهیم داشت. بنابر این نیاز به ارجاع هایی به پروژه های مربوطه خواهیم داشت.

ارجاع هایی را به پروژه های BusinessEntities، BusinessLogic و CommonLibrary ایجاد کنید.

اگر به خاطر داشته باشید در هنگام ایجاد لایه ی DataAccess از تعریف Connection String خودداری کرده و تصمیم گرفتیم از Connection String ی که بعدا در فایل Web.config تعریف خواهیم کرد استفاده کنیم. حال موقع آن رسیده است که Connection String مورد نظر خود را به فایل Web.config اضافه کنیم. 

از وب سایت مورد نظر فایل Web.Config را باز کرده و کد های زیر را به بخش configuration اضافه کنید:
<connectionStrings>
  <add name="eShop" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=db_eShop;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
همچنین نیاز داریم نام Connection String مورد نظر که قصد استفاده از آن را داریم (eShop) در بخش appSettings  که در همین فایل Web.config تعریف می شود نگهداری کنیم. برای این منظور کدهای زیر را نیز به بخش configuration اضافه نمایید:
<appSettings>
  <add key="ConnectionStringName" value="eShop" />
</appSettings>
در نهایت فایل Web.config شما باید به این شکل باشد:
<?xml version="1.0"?>

<configuration>

  <connectionStrings>
    <add name="eShop" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=db_eShop;Integrated Security=True" providerName="System.Data.SqlClient"/>
  </connectionStrings>

  <appSettings>
    <add key="ConnectionStringName" value="eShop" />
  </appSettings>
  
  <system.web>
    <compilation debug="false" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>

</configuration>
از آنجایی که قصد داریم تنظیمات دیگری از وب سایت را نیز در بخش appSettings نگهداری کنیم و به منظور جلوگیری از شلوغ شدن فایل Web.config این بخش را در یک فایل جداگانه با نام AppSettings.config تعریف کرده و به آن فایل ارجاع می دهیم. از طرف دیگر چون بسته به تنظیمات سرور ممکن است دسترسی به پوشه ی ریشه توسط ASP.NET و امکان ایجاد فایل های موقت (Temporary) که برای تغییر در این فایل مورد نیاز است وجود نداشته باشد این فایل را در پوشه ای با نام Settings تعریف خواهیم کرد تا در آینده امکان تغییر سطح دسترسی آن بر روی سرور را داشته باشیم.

در وب سایت مورد نظر پوشه ای با نام Settings ایجاد کرده و سپس فایلی از نوع Web Configuration File و با نام AppSettings.config در این پوشه ایجاد کنید. سپس محتوای آن را به این شکل ویرایش کنید:
<?xml version="1.0"?>

<appSettings>
  <add key="ConnectionStringName" value="eShop" />
</appSettings>
همچنین بخش appSettings در فایل Web.config را نیز به این شکل ویرایش نمایید:
<appSettings configSource="Settings\AppSettings.config"/>
در نهایت فایل Web.config شما باید به شکل زیر باشد:
<?xml version="1.0"?>

<configuration>

  <connectionStrings>
    <add name="eShop" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=db_eShop;Integrated Security=True" providerName="System.Data.SqlClient"/>
  </connectionStrings>

  <appSettings configSource="Settings\AppSettings.config"/>
  
  <system.web>
    <compilation debug="false" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>

</configuration>

همچنین ساختار پوشه های Solution شما به این شکل باید باشد:

022.png
در ادامه به تنظیم سیستم Membership برای استفاده از بانک مورد نظر خود خواهیم پرداخت و نقش ها و کاربران مورد نظر را ایجاد خواهیم کرد.

----------


## fire_love

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

----------


## clover

با سلام
تاپیک به روز رسانی شد و پست مربوط به ایجاد لایه ی Business Logic هم تکمیل شد. در صورتی که تا اینجای کار سوالی دارید و یا در مورد تاپیک انتقاد یا پیشنهادی دارید در همین تاپیک مطرح کنید.

با تشکر

----------


## fire_love

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

----------


## clover

رزرو برای تنظیمات Membership و ایجاد کاربران

----------


## clover

رزرو برای ایجاد پنل مدیریت

----------


## amirsajjadi

ممنون از مطالبی که گذاشتید. توی پروژه های گروهی که از تکنیک چندلایه استفاده میشه هیچ وقت مستقیم پیغام ها رو نمینویسن بلکه اونا رو از یک لایه به لایه بالاتر throw میکنن و در آخرین لایه اونا رو مدیریت میکنن. منظورم این نیست که پروژه شما درست نیست بلکه این نوعی که شما نوشتید برای پروژه های یک یا دو نفره کاربرد داره.
بازم تشکر میکنم از این تاپیک مفیدتون

----------


## mohammad kafiyan

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



> هیچ وقت مستقیم پیغام ها رو نمینویسن بلکه اونا رو از یک لایه به لایه بالاتر throw میکنن و در آخرین لایه اونا رو مدیریت میکنن

----------


## علی متقی پور

من آموزش رو کامل ندیدم ولی همنیکه دیدم هنوز از ado.net و sp استفاده کردید ترجیح دادم اصلا یادش نگیرم.

بابا جون مایکروسافت خودش ado.net را ایجاد کرده حالا EF5 هم اومده. تیم تولیدشون هم یکیه. آخه چه کاریه که بیائیم اینطوری کد بنویسیم؟

----------


## s.hoseinpoor

> من آموزش رو کامل ندیدم ولی همنیکه دیدم هنوز از ado.net و sp استفاده کردید ترجیح دادم اصلا یادش نگیرم.
> 
> بابا جون مایکروسافت خودش ado.net را ایجاد کرده حالا EF5 هم اومده. تیم تولیدشون هم یکیه. آخه چه کاریه که بیائیم اینطوری کد بنویسیم؟


شما می گید الان ما چیکار کنیم؟

----------


## clover

از نظراتی که دادید تشکر می کنم.




> ممنون از مطالبی که گذاشتید. توی پروژه های گروهی که از تکنیک چندلایه استفاده میشه هیچ وقت مستقیم پیغام ها رو نمینویسن بلکه اونا رو از یک لایه به لایه بالاتر throw میکنن و در آخرین لایه اونا رو مدیریت میکنن.


حرف شما کاملا درست هست، حقیقت اینه که من در ابتدا قصد داشتم پیغام ها رو در لایه ی Data Access هم به همین صورت فعلی تولید کنم اما به همین دلیلی که فرمودید منصرف شدم و سعی کردم این شیوه رو در همین لایه محدود کنم و به لایه های دیگه بسط ندم تا در آینده برای اعمال تصحیحات با مشکل حادی رو به رو نباشم. به هر حال ما در حال پیاده سازی یه فروشگاه اینترنتی ساده و جمع و جور هستیم که معمولا یک نفره طراحی میشه و در حال حاضر هم در بخش ASP.NET افراد زیادی در مورد پیاده سازی بخش های مختلفش (سبد خرید، ادیتور و فایل منیجر، شاخه بندی و ...) مشکل دارند و من ترجیح دادم در این مرحله به همین شیوه بسنده کنم و قضیه رو از این پیچیده تر نکنم  :لبخند:  اما تذکر شما مد نظرم هست و شاید پس از اتمام آموزش تغییراتی رو ایجاد کردم. در صورت تمایل می تونید نمونه هایی از شیوه ی مد نظر خودتون رو در همین تاپیک قرار بدید تا دوستان استفاده کنند. باز هم ممنون




> من آموزش رو کامل ندیدم ولی همنیکه دیدم هنوز از ado.net و sp استفاده کردید ترجیح دادم اصلا یادش نگیرم.


شما مختارید  :لبخند: 



> بابا جون مایکروسافت خودش ado.net را ایجاد کرده حالا EF5 هم اومده. تیم تولیدشون هم یکیه. آخه چه کاریه که بیائیم اینطوری کد بنویسیم؟


هدف من درک بهتر از ارتباط با پایگاه داده به دلیل نزدیکی بیشتر ADO.NET با پایگاه داده و درگیری بیشتر با کوئری ها از یک طرف و از طرف دیگه کد های میانی کمتر بود، همینطور کارایی بالاتر و سادگی فهم چگونگی کارکرد (و نه به کارگیری) ADO.NET هم مد نظرم بود. در ضمن به این نکته هم دقت کنید که Entity Framework در واقع بخشی از ADO.NET هست پس در هر صورت ما داریم از ADO.NET استفاده می کنیم اما من دارم از تکنولوژی های قدیمی تر ADO.NET و کلاس های سطح پایین تری استفاده می کنم و به شما اطمینان میدم این شیوه رو با آگاهی کامل انتخاب کردم. باز هم از اینکه انتقادتون رو مطرح کردید ازتون تشکر می کنم.

از دوستان خواهش می کنم باز هم اگر انتقاد، پیشنهاد یا نظری دارند مطرح کنند.

----------


## علی متقی پور

> شما می گید الان ما چیکار کنیم؟


منظورت را متوجه نشدم دوست عزیز

----------


## علی متقی پور

> از نظراتی که دادید تشکر می کنم.
> 
> 
> حرف شما کاملا درست هست، حقیقت اینه که من در ابتدا قصد داشتم پیغام ها رو در لایه ی Data Access هم به همین صورت فعلی تولید کنم اما به همین دلیلی که فرمودید منصرف شدم و سعی کردم این شیوه رو در همین لایه محدود کنم و به لایه های دیگه بسط ندم تا در آینده برای اعمال تصحیحات با مشکل حادی رو به رو نباشم. به هر حال ما در حال پیاده سازی یه فروشگاه اینترنتی ساده و جمع و جور هستیم که معمولا یک نفره طراحی میشه و در حال حاضر هم در بخش ASP.NET افراد زیادی در مورد پیاده سازی بخش های مختلفش (سبد خرید، ادیتور و فایل منیجر، شاخه بندی و ...) مشکل دارند و من ترجیح دادم در این مرحله به همین شیوه بسنده کنم و قضیه رو از این پیچیده تر نکنم  اما تذکر شما مد نظرم هست و شاید پس از اتمام آموزش تغییراتی رو ایجاد کردم. در صورت تمایل می تونید نمونه هایی از شیوه ی مد نظر خودتون رو در همین تاپیک قرار بدید تا دوستان استفاده کنند. باز هم ممنون
> 
> 
> شما مختارید 
> 
> هدف من درک بهتر از ارتباط با پایگاه داده به دلیل نزدیکی بیشتر ADO.NET با پایگاه داده و درگیری بیشتر با کوئری ها از یک طرف و از طرف دیگه کد های میانی کمتر بود، همینطور کارایی بالاتر و سادگی فهم چگونگی کارکرد (و نه به کارگیری) ADO.NET هم مد نظرم بود. در ضمن به این نکته هم دقت کنید که Entity Framework در واقع بخشی از ADO.NET هست پس در هر صورت ما داریم از ADO.NET استفاده می کنیم اما من دارم از تکنولوژی های قدیمی تر ADO.NET و کلاس های سطح پایین تری استفاده می کنم و به شما اطمینان میدم این شیوه رو با آگاهی کامل انتخاب کردم. باز هم از اینکه انتقادتون رو مطرح کردید ازتون تشکر می کنم.
> ...


سلام البته من نخاستم زیاد وارد فاز انتقاد بشم ولی حالا که خودت استقبال میکنی باید بگم: 1. من یقین داریم این به اصطلاح آموزش نوشته شما نیست و بهمین خاطر ضعف هاش رو به پای شما نمیذارم   2. این متن اصلا آموزش نیست. اینجا مثلا نوشته &quot;روی اسم پروژه راست کلیک کنید و گزینه کلاس را انتخاب کنید و بعد این کد ها را داخل کلاس پیست کنید&quot; آخه اینکه نشد آموزش. جالبه که تو کد ها چقدر هم از اتریبیوت استفاده شده !!! برادر من اون شاخ هاش هم هنوز خیلی از اتربیوت ها رو نمیشناسن چه برسه بنده نوعی. حالا تو اموزشی که نحوه کلیک راست کردن هم نوشته شده یک کلمه در مورد اینکه این کدها چین و برای چی نوشته شدن نیومده.   3. استفاده از sp در یک برنامه که فعالیت دیتا بیسی بسیار کمی هم داره چه معنایی داره؟ الان برنامه های بزرگ هم دیگه از sp استفاده نمیکنن چه برسه برنامه های ساده ای مثل یک ای شاپ. با اینکه من خودم بشخصه تی اسکیو ال نویسیم قوی تر از لینک نویسیم هست ولی بازم هیچ رقمه حاضر نیستم حتی از یک sp هم استفاده کنم. sp ها واقعا پر سرعتن. ولی دیگه دورانشون تموم شده. شما وقتی میخوای یه برنامه قابل توسعه و نگهداری داشته باشی. وقتی صحبت از بیزینس لاجیک لایر میکنی دیگه معنی نداره که بیای sp بنویسی و همه منطق برنامه رو با اون پیاده کنی.   4. نحوه ولیدیشن اطلاعات هم واقعا دیدنیه.    5. من فکر میکنم یه سری ازکد های قرار گرفته در اینجا توسط کد جنریتور ساخته شده   بهرحال میدونم خیلی جسته و گریخته و نا منظم نوشتم ولی میخاستم در حد سواد کم خودم بگم که این به اصطلاح آموزش بسیار ضعیف و غیر علمیه

----------


## clover

> 1. من یقین داریم این به اصطلاح آموزش نوشته شما نیست و بهمین خاطر ضعف هاش رو به پای شما نمیذارم


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




> 2. این متن اصلا آموزش نیست.


دلیل بیارید. مثالی زدید و گفتید راجع به فلان چیز توضیح نداده. یعنی اگر توضیح بده میشه آموزش؟ یا اشکالات دیگه ای هم داره؟ شاید هم کلا هیچ وقت نتونه آموزش بشه، نظرتون چیه؟




> حالا تو اموزشی که نحوه کلیک راست کردن هم نوشته شده یک کلمه در مورد اینکه این کدها چین و برای چی نوشته شدن نیومده


جالب تر اینه که تا حالا حتی یک نفر هم نپرسیده این کدها چی هستند  :لبخند:  در چند تا سوالی که تا الان به صورت خصوصی به دست من رسیده بیشتر در مورد مفاهیمی که در پروژه های Visual Studio مطرحه مثل نوع پروژه ها، تنظیمات و ... و همینطور مسایل مربوط به پایگاه داده سوال پرسیده شده. به طور مثال از من پرسیده شده Solution چی هست. پس به من حق بدید که به جای اینکه بگم "یک Solution جدید ایجاد کنید" بیام و حتی در مورد کلیک کردن روی فلان گزینه هم بنویسم. چون هدف اینه که از توقف و دلسردی کسی که داره از این متن استفاده میکنه، به خاطر اینکه ممکنه ندونه Solution چی هست و چطوری ایجاد میشه جلوگیری کنم.




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


در هر صورت من در مورد SP ها نمی تونم صحبت شما رو قبول کنم و دلایل شما برای عدم استفاده از SP ها برام قانع کننده نیست.




> 4. نحوه ولیدیشن اطلاعات هم واقعا دیدنیه.


متوجه هستم  :لبخند:  اما فکر می کنم تا همین حد برای اینکه یه شخص مبتدی درک کنه به طور مثال لایه ی Business Logic چه کاری داره انجام میده کافیه. شما پیشنهادات خودتون رو به همراه مثال در همین تاپیک بگذارید تا بقیه استفاده کنند.




> 5. من فکر میکنم یه سری ازکد های قرار گرفته در اینجا توسط کد جنریتور ساخته شده


هیچکدوم توسط کد جنریتور ساخته نشده، قصد من هم همین بوده.

اما یک توضیح کلی راجع به انتقاد شما میدم. من چند سالی هست که داخل این تالار فعالیت می کنم و خیلی زیاد به کاربرانی برخوردم که توی ASP.NET در مورد مسایل به صورت جزیی (گسسته) اطلاعات دارند (مثلا اتریبیوت ها، برنامه نویسی شی گرا، چند لایه و ...) اما نمی دونند که چطور باید از این اطلاعات در طول یک پروژه استفاده کنند. نمی دونند از کجا باید شروع کنند و به کجا ختم کنند. از طرف دیگه کاربرانی رو دیدم که با داشتن همین اطلاعات حتی نمی تونند از کدها و پروژه های آماده استفاده کنند چون نمی دونند که به طور مثال بانک رو کجا باید ایجاد کنند و چطور به برنامه متصل کنند. کد ها رو کجا باید بنویسند و ... شاید خیلی از مواردی که به نظر شما ضعف میرسه حتی نقطه ی قوت این آموزش باشه. خیلی ها حوصله مطالعه ندارند و دوست دارند فقط سریع نرم افزار ساخته بشه و شروع به کار کنه. خیلی ها به خاطر بی اطلاعی از مسائل بسیار جزیی نمی تونند از آموزش ها استفاده کنند و من جامعه ی هدف این آموزش رو این افراد در نظر گرفتم.

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




> بهرحال میدونم خیلی جسته و گریخته و نا منظم نوشتم ولی میخاستم در حد سواد کم خودم بگم که این به اصطلاح آموزش بسیار ضعیف و غیر علمیه


همین که وقت گذاشتید و این مسائل رو مطرح کردید ازتون تشکر می کنم.

موفق باشید

----------


## fire_love

> اما یک توضیح کلی راجع به انتقاد شما میدم. من چند سالی هست که داخل این تالار فعالیت می کنم و خیلی زیاد به کاربرانی برخوردم که توی ASP.NET در مورد مسایل به صورت جزیی (گسسته) اطلاعات دارند (مثلا اتریبیوت ها، برنامه نویسی شی گرا، چند لایه و ...) اما نمی دونند که چطور باید از این اطلاعات در طول یک پروژه استفاده کنند. نمی دونند از کجا باید شروع کنند و به کجا ختم کنند.



و من یکی از همین کاربر ها هستم . یعنی با این آموزش کلی اطلاعات بدست آوردم . برای من که فوق العاده مفید بود و همچنان منتظر قسمتهای بعدی اون هستم . مرسی

----------


## علی متقی پور

با سلام مجدد
شاید من این آموزش رو تائید نکنم ولی واقعا نوع برخورد شما با انتقادات و ادب پاسخگوئیتون رو نه تنها تائید میکنم بلکه تحسین هم میکنم.

من واقعا نمیتونم درک کنم که اون کسائیکه معتقدند این آموزش براشون مفیده چه فکری دارن و اینکه اصولا چطور شما معتقدید که کسیکه نمدونه سلوشون چیه باید بهش آموزش ساخت eShop را داد. ولی میدونم که مهم رضایت استفاده کنندگان آموزشه نه من. البته من یه مقدار به آقا یا خانوم fire_love هم مشکوکم :-)

----------


## fire_love

> البته من یه مقدار به آقا یا خانوم fire_love هم مشکوکم :-)


منظورتون از مشکوک بودن چیه ؟ امیدوارم یکم بیشتر به هم احترام بزاریم و اینقدر همدیگه رو قضاوت نکنیم . هر چند این از ویژگیهای دیرینه ما ایرانی هاست 
مرسی

----------


## maktab

> من آموزش رو کامل ندیدم ولی همنیکه دیدم هنوز از ado.net و sp استفاده کردید ترجیح دادم اصلا یادش نگیرم.


سلام. من هم آموزش را نخوندم ولی این صحبتتون برام جالب بود. چرا میگید نباید از sp استفاده بشه؟ میشه علتش رو بگید چون همه جا میگن بهتره همیشه از sp استفاده کنیم.

----------


## mohamad ali sh

ببخشید دوست عزیز من یه سؤال کلی دارم
البته متن آموزش رو کامل نخوندم ولی تیکه تیکه نگاه انداختم به نظر واضح و خوب بود معلومه وقت زیادی گذاشتید،سؤالم اینه که خیلی وقته از sp و اون نوع ارتباط پایگاه داده استفاده نمی کنم،از   linq - EF استفاده می کنم،کاره درستی می کنم یا بهتره از همون روش قدیم استفاده کرد؟
یه درخواست هم دارم که اگه ممکنه یه رفرنس MVC هم بدید که به واضحیه آموزش خودتون باشه چون به دلیل کمبود وقت نرسیدم رفرنس های زبان اصلی و پیچیده رو بخونم
با سپاس از لطف شما

----------


## ahmad156

در مورد عدم کارایی Stored Procedure با وجود Entity Framework هم جایی مقاله ای خوندم ولی منبعش یادم نمیاد.
توی مقاله گفته بود که تمام مزیت های Stored Procedure ها رو EF پوشش میده که یکی از اونها جلوگیری از Sql Enjection ها بود

----------


## علی متقی پور

> منظورتون از مشکوک بودن چیه ؟ امیدوارم یکم بیشتر  به هم احترام بزاریم و اینقدر همدیگه رو قضاوت نکنیم . هر چند این از  ویژگیهای دیرینه ما ایرانی هاست 
> مرسی


سلام دوست عزیز
فکر مکینم کاملا واضح بود که شوخی کردم باهات
بهر حال حتی اگر من بد همب اشه بهتره بدی من رو به پای بدی همه ایرانی ها نذارید





> سلام. من هم آموزش را نخوندم ولی این صحبتتون برام جالب بود. چرا میگید نباید از sp استفاده بشه؟ میشه علتش رو بگید چون همه جا میگن بهتره همیشه از sp استفاده کنیم.


sp ها از نظر سرعت و پرفورمنس بی رقیبند. ولی چند تا اشکال دارن:
1. برنامه رو به دو قسمت کد ها عادی برنامه و sp ها تقسیم میکنند
2. دیباگشون سخته
3. بر مبنای اصول ری یوزیبیلیتی کار نمیکنن. یعنی در اکثر موارد اصلا قابل استفاده مجدد نیستن
4. وقتی شما بفرض بخواهید برنامه رو تغییر یا توسعه بدید کارتون رو سخت میکنن.
5. اگر دیتا بیس شما عوض بشه دیگه هیچ فایده ای ندارن و زحمت شما هدر رفته
6. ...

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

----------


## Saber_Fatholahi

با تشکر از زحمات شما
البته من هم یک پروژه متن باز گذاشتم روی وب "فروشگاه اینترنتی با معماری سه لایه" بد نیست نگاهی بهش بندازین
موفق و موید باشید

----------


## Saber_Fatholahi

> در مورد عدم کارایی Stored Procedure با وجود Entity Framework هم جایی مقاله ای خوندم ولی منبعش یادم نمیاد.
> توی مقاله گفته بود که تمام مزیت های Stored Procedure ها رو EF پوشش میده که یکی از اونها جلوگیری از Sql Enjection ها بود


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

----------


## farhad26

این اموزش با ASP.net Web Form هست یا Asp.net MVC  ؟؟

----------


## ahmad156

> سلام بله درست مطالعه کردین
> یکی از لینکهاش این سایته


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

----------


## ad.davachi

سلام چرا آموزشتون رو کامل نکردید؟

----------


## clover

> سلام چرا آموزشتون رو کامل نکردید؟


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

----------


## ad.davachi

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

----------


## hojjatshariffam

من کدهاتونو و آموزشتونو خوندم
برخلاف گفته های دوست عزیز *a_mottaghi_pour* آموزش خوبیه
من همه این کدارو بلد بودم و طرز استفادشونم بلد بودم ولی در بین گفته ها ممکنه بعضی افزار نکات ریزی رو یاد بگیرند . درسته که یه ذره قسمت های کلیک روی فلان قسمت و ... حوصله آدمو سر ببره ولی ممکنه برا بعضی هم این قسمتاش آموزنده باشه
تنها قسمتایی که یه نظر منم گنگ اومد همون اتریبیوت ها هستند که یا باید همینجا بیشتر توضیح داده بشه ویا اینکه یه ذره هم خودمون زحمت بکشیم و بریم سراغشون . من با بعضی از اونا قبلا آشنا بودم ولی اینجا هم با بعضی دیگش آشنا شدم
به هر حال از دوستمون ممنونم و منتظر بقیه آموزش هستم
در مورد استورد پریسجر ها هم من نظرم اینه که ازشون استفاده نکنیم بهتره چون ..... (قبلا بهشون اشاره شده) ولی من خودم هیچ وفت ازشون استفاده نکردم چون اصلا بلد نیستم ولی باز نظرم همونه
موفق باشد

----------


## babak2000

خیلی عالی هست مشتاقانه منتظر ادامه مطلب شما هستم دوست عزیز از انتقادهای به جا و بی جا بعضی از کاربران ناراحت نشید 

بهر حال این کد نویسی و تجربه شما هست که داره آموزش داده میشه دیگران اگه راه کارهای بهتری سراغ دارند 

میتونند ارائه کنند نه اینکه صرفآ اشکال بگیرند توی کدنویسی حرف زدن خیلی راحت هستش ولی در عمل .....  

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

----------


## علی متقی پور

> من کدهاتونو و آموزشتونو خوندم
> برخلاف  گفته های دوست عزیز  *a_mottaghi_pour*  آموزش خوبیه
> من همه این کدارو بلد بودم و طرز استفادشونم بلد بودم ولی  در بین گفته ها ممکنه بعضی افزار نکات ریزی رو یاد بگیرند . درسته که یه  ذره قسمت های کلیک روی فلان قسمت و ... حوصله آدمو سر ببره ولی ممکنه برا  بعضی هم این قسمتاش آموزنده باشه
> تنها قسمتایی که یه نظر منم گنگ اومد  همون اتریبیوت ها هستند که یا باید همینجا بیشتر توضیح داده بشه ویا اینکه  یه ذره هم خودمون زحمت بکشیم و بریم سراغشون . من با بعضی از اونا قبلا  آشنا بودم ولی اینجا هم با بعضی دیگش آشنا شدم
> به هر حال از دوستمون ممنونم و منتظر بقیه آموزش هستم
> در  مورد استورد پریسجر ها هم من نظرم اینه که ازشون استفاده نکنیم بهتره چون  ..... (قبلا بهشون اشاره شده) ولی من خودم هیچ وفت ازشون استفاده نکردم چون  اصلا بلد نیستم ولی باز نظرم همونه
> موفق باشد


شما با همه حرفای من موافقید ولی مخالفید؟!!!!!!
بهرحال اینکه ایشون آموزششون رو ارائه ندادن مربوط به انتقاد بنده یا سایر دوستان نمیشه.
ممکنه منبعی که ازشون این به اصطلاح آموزش رو کپی میکردن دیگه باقی مطلب رو نذاشته باشه :)
اگر  خودشون می نویسن که جالبه قبل از اتمام آموزش اونو منتشر کردن. مثه سریال  های آبکی ایرانی که هنوز تموم نشدن منتشر میشن و آخرش میشم مثه قهوه تلخ!





> خیلی عالی هست مشتاقانه منتظر ادامه مطلب شما هستم دوست عزیز از انتقادهای به جا و بی جا بعضی از کاربران ناراحت نشید 
> 
> بهر حال این کد نویسی و تجربه شما هست که داره آموزش داده میشه دیگران اگه راه کارهای بهتری سراغ دارند 
> 
> میتونند ارائه کنند نه اینکه صرفآ اشکال بگیرند توی کدنویسی حرف زدن خیلی راحت هستش ولی در عمل .....  
> 
> امیدوارم ادامه پیدا کنه


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

----------


## babak2000

> من آموزش رو کامل ندیدم ولی همنیکه دیدم هنوز از ado.net و sp استفاده کردید ترجیح دادم اصلا یادش نگیرم.
> 
> بابا جون مایکروسافت خودش ado.net را ایجاد کرده حالا EF5 هم اومده. تیم تولیدشون هم یکیه. آخه چه کاریه که بیائیم اینطوری کد بنویسیم؟


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



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


شما استاد مایکروسافت بغیر از تیکه انداختن مثل اینکه کار دیگه ای ندارید 

متاسفانه از این کاربرانی که تاپیک دیگران را خراب میکنند کم نیستن و هیچوقت هم یاد نمیگیرند
اگه سوالی یا انتقادی دارند مودبانه و بدون حاشیه بپرسند و ... . بگذریم ....

----------


## saeed_sho

استورد پروسیجرو ول کنید لطفا کمی در مورد سبد خرید توضیح بدین

----------


## علی متقی پور

> آقا مگه کسی شما  را مجبور کرده بیاییداز ado استفاده کنید هر چی دوس داری استفاده کن
> 
> 
> شما استاد مایکروسافت بغیر از تیکه انداختن مثل اینکه کار دیگه ای ندارید 
> 
> متاسفانه از این کاربرانی که تاپیک دیگران را خراب میکنند کم نیستن و هیچوقت هم یاد نمیگیرند
> اگه سوالی یا انتقادی دارند مودبانه و بدون حاشیه بپرسند و ... . بگذریم ....


فدای ادبیات 2013 ایت بشم من داداش. بذار بدون دعوا کمی علمی جوابت رو بدم.
ببین عزیزم راه های زیادی برای نوشتن یک برنامه وجود داره. اما گذشتگان من و شما که نور به قبرشون بباره طبق تجربه متوجه شدن که برای توسعه و نگهداری نرم افزارهای موجود باید استاندارد هایی رو در زمان کدننویسیشون رعایت کرد. از قبوله فانکشنال بودن برنامه، استقلال وظایف، کپسولیشن و ...
یکی از رو های بروز برای توسعه نرم افزار n-tire نوشتن اونه. یعنی اینکه طبق سناریو یک اپلیکیشن اینترپرایز رو به لایه های مختلف تقسیم کنیم و این لایه ها رو با نهایت استقلال ممکن طراحی کنیم. یکی از معروف ترین n های این روش، روش سه لایه است. پس هر وقت صحبت از سه لایه میشه بدون که برنامه قراره طبق اصول استاندارد نوشته بشه وگرنه که با کد پشت فرم هم میشه نرم افزار نوشت!!!
وقتی حرف از استاندارد میاد وسط دیگه شما نمیگی silverlight بهتر از html5 هست. ممکنه شما دوست داشته باشی ازش استفاده کنی ولی نمیتونی ادعا کنی که بهتره. اینها طبق سلیقه بنده و شما نیست. کتابخونه نیست که شما آزاد باشی انتخاب کنی. ممکنه شما جی کوئری را دوست داشته باشی و من مثلا بخوام برم دنبال EXT js !
استاندارد 2013 اینه که شما برنامه دات نتتون رو شی گرا، چند لایه، و ترجیحا CodeFirst یا ModelFirst بنویسی. همین استاندارد ها میگن که شما باید برنامتون قابلیت خطایابی داشته باشه. باید بشه تستش کرد. باید کدها قبل از اجرا قابل بررسی بشن. همین استاندارد ها میگن که باید منطق برنامه شما تو کد شما باشه نه تو دیتابیستون. دیتا بیس محل ذخیره دیتای شماست نه منطق شما.
مایکروسافت اومده ado رو ایجاد کرده. دمش هم گرم. ولی خودش میدونه که ado به تنهایی نمیتونه ایراد بزرگ شی گرا نبودن SQl Server را حل کنه. مایکروسافت میاد یه ORM برای حل این مشکل ایجاد میکنه. این ORM هر چند اولش خیلی ضعیف بود ولی الان به یه بلوغی رسیده. یک برنامه شی گرای واقعی که بصورت n لایه پیاده سازی میشه باید و باید منطقش داخل لایه بیزینسش باشه ( نه داخل دیتابیسش) و ضمنا باید بصورت شی گرا با دیتا بیس تعامل داشته باشه.
همه اینها یعنی SP و ado دیگه جوابگو نیستن. ado فوق العادس اما وقتی با روکشی بنام EF روش پوشیده بشه.
وقتی من نوعی میام آموزش ساخت فروشگاه اونم به روش سه لایه میذارم باید توش بجای SP از linq و خود Csharp استفاده کنم. برنامم رو با استفاده از EF شی گرا کنم. و با پیاده سازی منطقم در BLL بجای DAL به حرف خودم مبنی بر سه لایه بودن برنامم عمل کنم.
این شد بخش اول حرف من که اصلا این برنامه از اساس غلطه.
بحث دوم هم اینه که اصلا ایجا آموزشی داده نشده. مطمئن باش بنده نمیخوام شمای نوعی رو به گمراهی بکشم. دوست دارم شما چیزهای بروز رو یاد بگیری نه به سبک 9 سال پیش برنامه دولوپ کنی.
پس بجای اینکه بذر کینه و نفرت رو تو دل هم بذاریم بهتره با منطق و علم بیائیم جلو

----------


## hojjatshariffam

> همه اینها یعنی SP و ado دیگه جوابگو نیستن. ado فوق العادس اما وقتی با روکشی بنام EF روش پوشیده بشه.
> وقتی من نوعی میام آموزش ساخت فروشگاه اونم به روش سه لایه میذارم باید توش بجای SP از linq و خود Csharp استفاده کنم. برنامم رو با استفاده از EF شی گرا کنم. و با پیاده سازی منطقم در BLL بجای DAL به حرف خودم مبنی بر سه لایه بودن برنامم عمل کنم.


خب همه اینا قبول دوست عزیز
شما با این نوشتتونم نشون میده که آموزش و تشریح مساعلتونم خوبه
پس اگه لطف کنید و وقتشو داشته باشد به جای اینکه تو سرو کله هم بزنیم می تونید مثلا اتریبیوت ها رو شما توضیح بدید
یا همون EF رو شما اضافه کنید و بگید که به جای SP ها می تونید به این صورت بنویسید
من خودم یه جنیریتور نوشتم و به به سلیقه خودم بیزینس لییر رو می نویسم ولی صرفا شاید اونم درست نباشه و اشکالاتی داشته باشه
پس شمام لطف کنید که (البته گفتم اگه می تونید و وقتشو دارد) آموزش بدین ، می تونه اصلاحیه روش های گفته شده باشه
ضمنا شما می تونید کلی تر توضیح بدین

----------


## ad.davachi

با *hojjatshariffam* موافقم .
این جناب *a_mottaghi_pour* توی کل پستهاش یه پست آموزشی یا سوال کلیدی نپرسیده که نشون دهنده برنامه نویس بودنش باشه هرجا رفته یا با مدیر های سایت دعوا راه انداخته یا همه جا اومده از برنامه نویس ها ایراد گرفته یه جا هم نوشته من فلسفه خوندم و شما مهندسها .... هستین

باید بگم بر خلاف شما بچه های انسانی ما مهندس ها ادعامون رو تو عمل ثابت میکنیم.

بابا تو که انقد ادعات میشه پس کو یال و کوپالت؟

----------


## علی متقی پور

> با *hojjatshariffam* موافقم .
> این جناب *a_mottaghi_pour* توی کل پستهاش یه پست آموزشی یا سوال کلیدی نپرسیده که نشون دهنده برنامه نویس بودنش باشه هرجا رفته یا با مدیر های سایت دعوا راه انداخته یا همه جا اومده از برنامه نویس ها ایراد گرفته یه جا هم نوشته من فلسفه خوندم و شما مهندسها .... هستین
> 
> باید بگم بر خلاف شما بچه های انسانی ما مهندس ها ادعامون رو تو عمل ثابت میکنیم.
> 
> بابا تو که انقد ادعات میشه پس کو یال و کوپالت؟


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

شما از آقا حجت مایه گذاشتی و خاستی نشون بدی که نظر ایشون هم مثل نظر شماست درحالیکه بهتر بود از دوست فوق العاده عزیزم آقا بابک گل مایه میذاشتی. چون ایشون هستن که با شما موافقن و البته همه ازادن هر نظری میخوان داشته باشن ولی از نوشته ها مشخصه چه کسی بحث علمی کرده و چه کسی دعوا و توهین و افتراء داشته.

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

----------


## Mousavmousab

سلام

فکر می کنم اگه شما یک فایل Video ای از این توضیحات فراهم می کردین  خیلی راحت تر و کاربردی تر بود.
درست نمی گم دوستان ؟ البته این نظر منه !!!
به هر حال موفق باشید

----------


## hojjatshariffam

ما که منتظریم ببینمی بقیش چی میشه
حالا اونی که تاپیک زده یا یکی دیگه
ایشالا ادامه پیدا میکنه

----------


## aspmaker

من این تاپیک رو از اول خوندم
چیزایی که تا اینجا آموزش داده شده هنوز جزء مسائل اولیه برای ساخت وب چند لایه است و برخی از بخش ها برای تاپیکی که اموزش گام به گام هست کمبود و کاستی داره که تغییراتی رو میطلبه داشته باشه (این دوستمون هم داره یه زمانی رو برای آموزش سایر دوستان میزاره پس از کارش دلسردش نکنید)، گرچه تاپیک از مسیر آموزشی به بحث علمی تبدیل شد اما یادمون باشه که آموزش اولیه گاهی لازمه. کی لازمه؟ وقتی که فردی که دارید براش آمورش میزارید توی اون زمینه تجربه کافی نداشته باشه. پس اگر جایی توضیحات برای برخی از دوستان ابتدایی اومد بهتره مته به خشخاش نزارن و بجاش با پیشنهاد سازنده بحث رو توی بهتر شدن هدایت کنن.
حرف آقای a_mottaghi_pour هم در ارتباط با آموزش به روز و استفاده کردن از EF به جای SP به جا  و درست هست چون همونطور که عزیزان گفتن استفاده از SP کنترل برنامه نویس روی کدهارو، از SCOPE کدها خارج میکنه و میره توی SQL که واقعاً گاهی اوقات که به مشکل میخوریم، دیباگ و دیدن نتایج کوئری ها و ... توی SP سخت میشه اما در عین حال مزایای خودش رو هم داره. ولی حالا که ما داریم با تکنولوژی کار رو پیش میبریم بهتر هست که از EF استفاده بشه که به روز تر هم هست.
در آخر هم باید بگم درخت هر چه پر بارتر افتاده تر. همدیگر رو با اطلاعاتمون له نکنیم چون بالاخره دست بالای دست بسیار هست و اینکه میتونیم به جاش با دانسته هامون همدیگه رو حمایت کنیم.


موفق باشید.

----------


## soha_smb

میشه بجای ضایع کردن همدیگه 
یه آموزش جامع و کامل از EF  بزارین
با تشکر.

----------


## Saber_Fatholahi

> میشه بجای ضایع کردن همدیگه 
> یه آموزش جامع و کامل از EF  بزارین
> با تشکر.


 دوست عزیز اینم آموزش جامع و مرحله به مرحله Entity Framework به زبان شیرین پارسی

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

----------


## fmka2f

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

----------


## fmka2f

> عزیز دلم برای کوبیدن من باید کمی فکر شده تر پست میذاشتی عزیزم
> الان که دارم اینو مینویسم طبق آمار شما 40 تا پست گذاشتی، 14 بار تشکر کردی و فقط 2 بار تشکر شدی. بنده نیز قبل از این پست 127 تا پست داده بودم. یعنی 3 ممیز 175 صدم برابر شما. اگر نشبت بگیریم وقتی شما تعداد ست هاتون به تعداد من برسه 45 بار از پست هایدیگران تشکر کردی در حالیکه من 250 بار تشکر کردم. یعنی مشخصه که بنده بسیار بیشتر از شما قدر پست های خوب فروم رو دونستم بو جای حرف زدن الکی سعی کردم مطالب رو بخونم و از مطالب خوب در حد ممکن تقدیر و تشکر کنم. بازم اگر نسبت بگیریم وقتی شما به تعداد من پست گذاشته باشی 6 یا 7 بار تشکر شدی درحالیکه بنده 77 بار تشکر گرفتم.
> فکر میکنم آمار گویا باشه. نیازی ه هیچ عذر و بهانه و بیانیه ای نیست. اعضای انجمن هم نه داداش منن نه داداش شما. آمارو بازخورد ها بهترین قاضی هست. افرادیکه کم تشکر شدن یا کم تشکر کردن هر دو از نظر من مشکل دارن. جناب فتح اللهی یکی از عزیزان مورد علاقه و مورد تائید بنده هست ولی بهر حال کسیکه بعد از 7 سال عضویت در فروم تنها 5 بار تشکرکرده میتونه گواه خیلی مسائل باشه.
> عزیز دلم نه من شما رو میشناسم نه شما منو. ولی اینو بدون بعضی چیزها با ادعا بدست نمیاد. با حلوا حلوا کردن هم زبون شیرین نمیشه. 6 ماه پیش من تو همین فروم دنبال کسی میگشتم بعنوان کارآموز قبولم کنه اما امروز خودم آگهی استخدام دادم. نتیجه تلاش همه آدمها مشخصه.


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

----------


## artabaz

جا داره از همه دوستانی که در این تاپیک شرکت کردند هم از دوست عزیزمون که این تاپیک رو ایجاد کرد و دوستانی که انتقاد کردند، مخصوصا جناب Saber_Fatholahi که کامنتاشون واقعا به جا و مفید بود( پروژه ای که هم که ساخته بودن رو دانلود کردم و پیشنهاد میکنم ازش استفاده کنید)،  به نوبه خودم تشکر کنم.
مطمئنن کسانی که میان این تاپیک، همه در یک سطح نیستند، هر کدوم با سطح سواد خودش، به هر شکلی مطلبی را اینجا یاد میگیره، یا با همون مطلب شروع آموزش ، یا با انتقادها ، یا هم با لینکهایی مثل لینکهایی که جناب Saber_Fatholahi گذاشتند، (خودم به شخصه از همه استفاده کردم حتی از بعضی انتقادهای جناب a_mottaghi_pour ).
پس جه بهتر اگه دوستانی هم که میبنند کم و کاستی های این آموزش چی و کجای هستند، در صورت امکان  خودشون آموزش بدند و یا حداقل مرجعی رو معرفی کنند..
موفق و سربلند باشید

----------


## علی متقی پور

> خودم به شخصه از همه استفاده کردم حتی از بعضی انتقادهای جناب a_mottaghi_pour


داداش گلم همچین اسم منو میاری انگار من یک جذامی هستم :)
درد همه ماها بیسوادیه. بحث علمی را سریع شخصیتیش میکنیم چونکه سواد لازم برای بحث رو نداریم. n تا پست داده شد یکیش در مورد محتوای انتقاد من نبود فقط چون صاحب تاپیک ول کرده و رفته همه گیر دادن بمن . منم که بیدی نیستم که از این بادها بلرزم. هر کی حرف علمی داره بزنه ما استفاده کنیم. جالبه که صاحب تاپیک حتی همین امروز هم به فروم سر زده ولی نیومده در مورد تاپیک خودش حرفی بزنه ولی بقیه شدن کاشه داغتر از آش. داداش وقتی یه اموزشی از بنیان ایراد داره و طرف خودش متوجه شده مودبانه بی خیالش شده. دیگه اینقد کش دادن نداره

----------


## artabaz

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

----------


## vahid_pitok

سلام خدمت دوستان عزیز

من سایت رو با این معماری درست کردم حالا چطوری باید Uploadesh کنم میشه طریقه publish کردن با این نوع معماری رو آموزش بیدین؟

ممنون

----------


## alireza.tofigh

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

----------


## AmirhossenFekri

> داداش گلم همچین اسم منو میاری انگار من یک جذامی هستم :)
> درد همه ماها بیسوادیه. بحث علمی را سریع شخصیتیش میکنیم چونکه سواد لازم برای بحث رو نداریم. n تا پست داده شد یکیش در مورد محتوای انتقاد من نبود فقط چون صاحب تاپیک ول کرده و رفته همه گیر دادن بمن . منم که بیدی نیستم که از این بادها بلرزم. هر کی حرف علمی داره بزنه ما استفاده کنیم. جالبه که صاحب تاپیک حتی همین امروز هم به فروم سر زده ولی نیومده در مورد تاپیک خودش حرفی بزنه ولی بقیه شدن کاشه داغتر از آش. داداش وقتی یه اموزشی از بنیان ایراد داره و طرف خودش متوجه شده مودبانه بی خیالش شده. دیگه اینقد کش دادن نداره


جناب mottaghi_pour ، با همه این تفاسیر انتقاد در کنار راهکار دادن مفیده ، شما حمله کردید به آموزش این دوستمون (اینکارتون خوب نبود) از نظر بنده . 
حالا دیگه از حاشیه خارج بشیم بهتره ، هرکی هر کمکی میتونه انجام بده ، شما هم میتونی حسن نیتت رو با کمک کردن به ادامه بحث ثابت کنی. اگه جایی مشکل وجود داره بهتر نیست به رفع و بالا بردن سطح دوستانمون بپردازیم تا گفتگوهای بیخودی؟

با تشکر از *clover*

----------


## salehi_so

اقا پس بقیه آموزش چی شد؟

----------


## peromo

دوست عزیز و گرامی *a_mottaghi_pour* اینکه شما خدای برنامه نویسی هستی برهمگان اثبات شد
شما اگر بلدی آموزش بدی خوب دوست من همه مشتاق هستند یاد بگیرن
اگر نه که بزار کسایی که میخوان چیزی یاد بگیرن یاد بگیرن. اینجا جایی برای یادگیری و آموختن و یاد دادنه
یک تاپیک دیکه ایجاد کنید و در اون به بحث پیرامون معایب و مزایای تکنولوژی های نو ظهور و گذشته بپردازید
من نمیدونم ما چیو می خوایم اثبات کنیم

----------


## mahdinn

خسته نباشی داداش لطف میکنی بقیه آموزشتو بذاری.. تا اینجاش که توضیح دادی من یکی خیلی استفاده کردم.لطف کن باقی شم بذار

----------


## sanay_esh

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

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

اینجا برای کسی اجباری نیست که پیام بذاره.... هر توانست طبق قوانین و مقررات این سایت عمل کنه انسان موفقی هست. 

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

از  همه کاربران بعنوان یک عضو کوچک در این سایت خواهشی دارم : اینکه اگر کسی خارج از قوانین و مقررات و خارج از عرف و اخلاق عملی انجام داده با گزارش به مدیر تالار جلوی ایشان را بگیریم 

نه اینکه بشینیم یک تاپیک آموزشی ( با هر سطحی که باشد ) با پیام های کذایی خود خراب کنیم. 

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

----------


## علی متقی پور

با سلام خدمت آقای *sanay_esh* یا همون مهندس خلفی خودمون

اگر شما بنده رو بخاطر نداشته باشید بنده شما رو بخاطر دارم که چند سال پیش که دلار 1000 تومن بود و بنده نیز همانند دوستان این تاپیک با تکنولوژی linq و EF کار نمیکردم قصد داشتید در ازای دریافت یک میلیون و 200 هزار تومن!!!! بعضی تکنولوژی های جدیدتر رو بمن یاد بدی. ملاقاتمون تو آریاشهر رو حتما یادت نرفته. درسته؟
حالا نمیدونم چی شده که دعوت من از دوستان برای استفاده linq و EF بجای ado.net و Sp شده حرفهای سطح پائین. جریان چیه مهندس؟ یعنی هنوز هم از همین طریق کسب درآمد میکنی؟
اما امروز من خودم به همه زوایای تکنولوژی های جدید نیم نگاهی داشتم و متوجه شدم که عده ای چطور از نا آگاهی بعضی استفاده میکنن و نمیذارند که افراد طالب یادگیری دانششون رو به مرز تکنولوژی نزدیک کنند تا بتونند از همین طریق ارتزاق کنند.
دوست عزیزم اما من برخلاف شما چه به شاگردهای خودم چه اعضای تالار این نهیب رو میزنم تا فریب نخوردند و هر چه سریعتر سعی کنن دانش خودشون رو آپدیت کنند.
اگر شما تاپیک رو بخونید میبینید که ایجا کننده اون هرگز اعتراضی به انتقاد من نداشته بلکه بعدی ها [که البته سه تاشون اکانت فیک هستن و یکی از دوستان منحصرا برای شرکت در همین تاپیک ایجادشون کرده] اومدن و حرفایی رو زدن چون گمان کردن ادامه نیافتن آموزش مربوط به انتقاد من بوده در حالیکه مسائل دیگه ای هست که من به احترام آقای Clover زننده تاپیک چیزی از اون نمیگم.
شما هم اگر میخواهید نقش ناجی رو داشته باشید میتونید به ایشون یک پیام بدید و از ایشون بخواهید آموزششون رو ادامه بدن.
یا اینکه میتونید یک از ده ها پی دی اف رایگان موجود در اینترنت را به فایل وورد کانورت کرده و اونو بخش بخش کنید و بعنوان آموزش بنام خودتون منتشر کنید و کلی هم تشکر بگیرید.

----------


## bita bita

پس بقیه ش چی شد؟ :گریه:

----------

