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

سلام

نمیدونم عبارات و اصطلاحاتی که بکار میبرم درسته یا خیر.

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

تشکر

نظرات نظرسنجی‌ها
آیا برای ارایه مشاوره از مشتری هزینه ای درخواست می‌کنید؟
بدلیل اینکه تشریح برخی از موضوعات در حوزه پیاده سازی و توسعه، زمان بر هست و باید مسائل فنی و اورجینال‌های لازم را به مشتری توضیح دهیم بابت 4-3 ساعت مشاوره که در یک چشم بهم زدن سپری می‌شود هزینه ای برابر با 400 هزار تومان دریافت می‌گردد.
نظرات نظرسنجی‌ها
تا چه مدتی ترجیح می‌دهید در یک محل کاری باقی بمانید؟
به نظر من بیشتر از 1 سال منوط به شرایط کاری و محیطی شرکت هست که در بعضی مواقع نباید بیشتر از 1 سال در شرکتی ماند و در بعضی مواقع تا چندین سال می‌توان در یک شرکت ماند و کار کرد
خیلی بستگی به شرایط کار، محیط، مدیر فنی، مدیریت دارد.
مطالب
مسدود کردن آدرس IP با استفاده از IHttpModule در Asp.Net
 باسلام:
هدف این مقاله بیشتر آشنایی با HttpModule در قالب یک پروژه می‌باشد. 
قصد دارم در این مقاله یک روش برای مسدود کردن IP هایی که به هر روشی در سایت شما اقداماتی غیر عادی انجام دادن و شما قصد دارید سایت شما به اونها نمایش داده نشه بیان کنم.
دقت کنید که شما میتونید با تشخیص کاربر متخلف مثل کاربری که بیش از 5 بار اقدام به وارد کردن نام کاربری و رمز عبور کرده کنید و IP کاربر رو در جایی مانند DataBase ذخیره کنید و یک زمان براش ثبت کنید و تا 15 دقیقه بعد از اون دسترسی به سایت رو ازش بگیرید.
برای شروع من کلاس مربوطه رو  با نام IPBlockModule در پوشه App_Code میسازم:
 
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
 
public class IPBlockModule : IHttpModule
{
       public IPBlockModule()
       {
              // TODO: Add constructor logic here
       }
    public void Dispose()
    {
        //Dispose
    }
 
    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(Application_BeginRequest);
    }
 
    private void Application_BeginRequest(object source, EventArgs e)
    {
        HttpContext context = ((HttpApplication)source).Context;
        string ipAddress = context.Request.UserHostAddress;
        if (IsBlockedIpAddress(ipAddress))
        {
            context.Response.StatusCode = 403;
            context.Response.Write("Forbidden : The server understood the request, but It is refusing to fulfill it.");
        }
    }
 
    private bool IsBlockedIpAddress(string ipAddress)
    {
        //Here I have stored Ip addresses in String[]. you can also Store in database.
        string[] IPs = {            "117.196.35.121",
                                    "117.196.35.122",
                                    "117.196.35.123",
                                    "117.196.35.124",
                                    "127.0.0.1"
                       };
 
        foreach(string IP in IPs)
        {
            if(IP == ipAddress)
                return true;
        }
        return false;
   
    }
    
}
و در فایل web.config این کلاس رو اضافه میکنیم :
 <configuration>
       <system.web>
              <compilation debug="true" targetFramework="4.0"/>
              <httpModules>
                     <add name="IPBlockModule" type="IPBlockModule"/>
              </httpModules>
       </system.web>
</configuration>
میتونید متغیر آرایه ای IPs رو از پایگاه داده بخونید و کوئری رو با شرط مدت زمان سپری شده که معمولا 15 دقیقه هست بگیرید.

موفق باشید. 
مطالب
MEF و الگوی Singleton

در مورد معرفی مقدماتی MEF می‌توانید به این مطلب مراجعه کنید و در مورد الگوی Singleton به اینجا.


کاربردهای الگوی Singleton عموما به شرح زیر هستند:
1) فراهم آوردن دسترسی ساده و عمومی به DAL (لایه دسترسی به داده‌ها)
2) دسترسی عمومی به امکانات ثبت وقایع سیستم در برنامه logging -
3) دسترسی عمومی به تنظیمات برنامه
و موارد مشابهی از این دست به صورتیکه تنها یک روش دسترسی به این اطلاعات وجود داشته باشد و تنها یک وهله از این شیء در حافظه قرار گیرد.

با استفاده از امکانات MEF دیگر نیازی به نوشتن کدهای ویژه تولید کلاس‌های Singleton نمی‌باشد زیرا این چارچوب کاری دو نوع روش وهله سازی از اشیاء (PartCreationPolicy) را پشتیبانی می‌کند: Shared و NonShared . حالت Shared دقیقا همان نام دیگر الگوی Singleton است. البته لازم به ذکر است که حالت Shared ، حالت پیش فرض تولید وهله‌ها بوده و نیازی به ذکر صریح آن همانند ویژگی زیر نیست:
[PartCreationPolicy(CreationPolicy.Shared)]

مثال:
فرض کنید قرار است از کلاس زیر تنها یک وهله بین صفحات یک برنامه‌ی Silverlight توزیع شود. با استفاده از ویژگی‌ Export به MEF اعلام کرده‌ایم که قرار است سرویسی را ارائه دهیم :

using System;
using System.ComponentModel.Composition;

namespace SlMefTest
{
[Export]
public class WebServiceData
{
public int Result { set; get; }

public WebServiceData()
{
var rnd = new Random();
Result = rnd.Next();
}
}

}
اکنون برای اثبات اینکه تنها یک وهله از این کلاس در اختیار صفحات مختلف قرار خواهد گرفت، یک User control جدید را به همراه یک دکمه که مقدار Result را نمایش می‌دهد به برنامه اضافه خواهیم کرد. دکمه‌ی دیگری را نیز به همین منظور به صفحه‌ی اصلی برنامه اضافه می‌کنیم.
کدهای صفحه اصلی برنامه (که از یک دکمه و یک Stack panel جهت نمایش محتوای یوزر کنترل تشکیل شده) به شرح بعد هستند:
<UserControl x:Class="SlMefTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400">
<StackPanel>
<Button Content="MainPageButton" Height="23"
HorizontalAlignment="Left"
Margin="10,10,0,0" Name="button1"
VerticalAlignment="Top" Width="98" Click="button1_Click" />
<StackPanel Name="panel1" Margin="5"/>
</StackPanel>
</UserControl>

using System.ComponentModel.Composition;
using System.Windows;

namespace SlMefTest
{
public partial class MainPage
{
[Import]
public WebServiceData Data { set; get; }

public MainPage()
{
InitializeComponent();
this.Loaded += mainPageLoaded;
}

void mainPageLoaded(object sender, RoutedEventArgs e)
{
CompositionInitializer.SatisfyImports(this);
panel1.Children.Add(new SilverlightControl1());
}

private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(Data.Result.ToString());
}
}
}
با استفاده از ویژگی Import به MEF اعلام می‌کنیم که به اطلاعاتی از نوع شیء WebServiceData نیاز داریم و توسط متد CompositionInitializer.SatisfyImports کار وهله سازی و پیوند زدن export و import های همانند صورت می‌گیرد. سپس استفاده‌ی مستقیم از Data.Result مجاز بوده و مقدار آن null نخواهد بود.

کدهای User control ساده اضافه شده به شرح زیر هستند:

<UserControl x:Class="SlMefTest.SilverlightControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">

<Grid x:Name="LayoutRoot" Background="White">
<Button Content="UserControlButton"
Height="23"
HorizontalAlignment="Left"
Margin="10,10,0,0"
Name="button1"
VerticalAlignment="Top"
Width="125"
Click="button1_Click" />
</Grid>
</UserControl>

using System.ComponentModel.Composition;
using System.Windows;

namespace SlMefTest
{
public partial class SilverlightControl1
{
[Import]
public WebServiceData Data { set; get; }

public SilverlightControl1()
{
InitializeComponent();
this.Loaded += silverlightControl1Loaded;
}

void silverlightControl1Loaded(object sender, RoutedEventArgs e)
{
CompositionInitializer.SatisfyImports(this);
}

private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(Data.Result.ToString());
}
}
}
اکنون قبل از شروع برنامه یک break point را در سازنده‌ی کلاس WebServiceData قرار دهید. سپس برنامه را آغاز نمائید. تنها یکبار این سازنده فراخوانی خواهد شد (هر چند در دو کلاس کار Import اطلاعات WebServiceData صورت گرفته است). همچنین با کلیک بر روی دو دکمه‌ای که اکنون در صفحه‌ی اصلی برنامه ظاهر می‌شوند، فقط یک عدد مشابه نمایش داده می‌شود (با توجه به اینکه اطلاعات هر دکمه در یک وهله‌ی جداگانه قرار دارد؛ یکی متعلق است به صفحه‌ی اصلی و دیگری متعلق است به user control اضافه شده).

مطالب
تعامل با پایگاه داده با استفاده از EntityFramework در پروژه های F# MVC 4
در پست‌های قبلی (^ و^) با  template و ساخت کنترلر و مدل در پروژه‌های F# MVC آشنا شدید. در این پست به طراحی Repository با استفاده از EntityFramework خواهم پرداخت. در ادامه مثال قبل، برای تامین داده‌های مورد نیاز کنترلر‌ها و نمایش آن‌ها در View نیاز به تعامل با پایگاه داده وجود دارد. در نتیجه با استفاده از الگوی Repository، داده‌های مورد نظر را تامین خواهیم کرد. به صورت پیش فرض با نصب Template جاری (F# MVC4) تمامی اسمبلی‌های مورد نیاز برای استفاده از  در EF در پروژه‌های #F نیز نصب می‌شود.

پیاده سازی DbContext مورد نیاز
برای ساخت DbContext می‌توان به صورت زیر عمل نمود:
namespace FsWeb.Repositories

open System.Data.Entity
open FsWeb.Models

type FsMvcAppEntities() = 
    inherit DbContext("FsMvcAppExample")

    do Database.SetInitializer(new CreateDatabaseIfNotExists<FsMvcAppEntities>())

    [<DefaultValue()>] val mutable books: IDbSet<Guitar>
    member x.Books with get() = x.books and set v = x.books <- v
همان طور که ملاحظه می‌کنید  با ارث بری از کلاس DbContext  و پاس دادن ConnectionString یا نام آن در فایل app.config، به راحتی FsMVCAppEntities ساخته می‌شود که معادل DbContext پروژه مورد نظر است. با استفاده از دستور do متد SetInitializer برای عملیات migration فراخوانی می‌شود. در پایان نیز یک DbSet به نام Books ایجاد کردیم. فقط از نظر syntax با حالت #C آن تفاوت دارد اما روش پیاده سازی مشابه است.

اگر syntax زبان #F برایتان نامفهوم است می‌توانید از این دوره کمک بگیرید.

پیاده سازی کلاس BookRepository
ابتدا به کد‌های زیر دقت کنید:
namespace FsWeb.Repositories

type BooksRepository() =
    member x.GetAll () = 
        use context = new FsMvcAppEntities() 
        query { for g in context.Books do
                select g }
        |> Seq.toList
در کد بالا ابتدا تابعی به نام GetAll داریم. در این تابع یک نمونه از DbContext پروژه وهله سازی می‌شود. نکته مهم این است به جای شناسه let از شناسه use استفاده کردم. شناسه use دقیقا معال دستور {}()using در #C است. بعد از اتمام عملیات شی مورد نظر Dispose خواهد شد.
در بخش بعدی بک کوئری از DbSet مورد نظر گرفته می‌شود. این روش Query گرفتن در F# 3.0 مطرح شده است. در نتیجه در نسخه‌های قبلی آن (F# 2.0) اجرای این کوئری باعث خطا می‌شود. اگر قصد دارید با استفاده از F# 2.0 کوئری‌های خود را ایجاد نماید باید به طریق زیر عمل نمایید:
ابتدا از طریق nuget اقدام به نصب package  ذیل نمایید:
FSPowerPack.Linq.Community
سپس در ابتدا Source File خود، فضای نام Microsoft.FSharp.Linq.Query را باز(استفاده از دستور open) کنید. سپس می‌توانید با اندکی تغییر در کوئری قبلی خود، آن را در F# 2.0 اجرا نمایید.
query <@ seq { for g in context.Books -> g } @> |> Seq.toList
حال باید Repository طراحی شده را در کنترلر مورد نظر فراخوانی کرد. اما اگر کمی سلیقه به خرج دهیم به راحتی می‌توان با استفاده از تزریق وابستگی ، BookRepository را در اختیار کنترلر قرار داد. همانند کد ذیل:
[<HandleError>]
type BooksController(repository : BooksRepository) =
    inherit Controller()
    new() = new BooksController(BooksRepository())
    member this.Index () =
        repository.GetAll()
        |> this.View
در کد‌های بالا ابتدا وابستگی به BookRepository در سازنده BookController تعیین شد. سپس با استفاده از سازنده پیش فرض، یک وهله از وابستگی مورد نظر ایجاد و در اختیار سازنده کنترلر قرار گرفت(همانند استفاده از کلمه this در سازنده کلاس‌های #C). با فراخوانی تابع GetAll  داده‌های مورد نظر از database تامین خواهد شد.

نکته : تنظیمات مروط به ConnectionString را فراموش نکنید:
<add name="FsMvcAppExample"
     connectionString="YOUR CONNECTION STRING"
     providerName="System.Data.SqlClient" />
موفق باشید.

مطالب
کنترل نوع‌های داده با استفاده از EF در SQL Server
ورود سیستم‌های ORM مانند EF تحولی عظیم در در مباحث کار و تغییرات بر روی داده‌ها یا Data Manipulation بود. به طور خلاصه اصلی‌ترین هدف یک ORM، ایجاد فرامین شیء گرا به جای فرامین رابطه‌ای است؛ ولی در این بین نکات دیگری هم مد نظر گرفته شده‌است که یکی از آن‌ها پشتیبانی از چندین دیتابیس هست تا توسعه گران از یک سیستم واحد جهت اتصال به همه‌ی دیتابیس‌ها استفاده کنند و نیازی به دانش اضافه و سیستم جداگانه‌ای برای هر دیتابیس نباشد؛ مانند ADO که در دات نت به چندین دسته نقسیم شده بود و هم اینکه در صورتی که تمایلی به تغییر دیتابیس در آینده داشتید، کدها برای توسعه باز باشند و نیازی به تغییر سیستم نباشد.
ولی اگر کمی بیشتر به دنیای واقعی وارد شویم گاهی اوقات نیاز است که تنها بر روی یک دیتابیس فعالیت کنیم و یک دیتابیس نیاز است تا حد ممکن بهینه طراحی شود تا کارآیی بانک در حال حاضر و به خصوص در آینده تا حدی تضمین شود.
من همیشه در مورد EF یک نظری داشتم و آن اینست که با اینکه یک ORM، یک هدف مهم را در نظر دارد و آن اینست که تا حد ممکن استانداردهایی را که بین تمامی دیتابیس‌ها مشترک است، رعایت کند، ولی باز قابل قبول است اگر بگوییم که کاربران EF انتظار داشته باشند تا اطلاعات بیشتری در مورد sql server در آن نهفته باشد. از یک سو هر دو محصول مایکروسافت هستند و از سوی دیگر مطمئنا توسعه گران محصولات دات نت بیش از هر چیزی به sql server نگاه ویژه‌تری دارند. پس مایکروسافت در کنار حفظ آن ویژگی‌های مشترک، باید به حفظ استانداردهای جدایی برای sql server هم باشد.

تعدادی از برنامه نویسان در هنگام ایجاد Domain Model کم لطفی‌های زیادی را می‌کنند که یکی از آن‌ها عدم کنترل نوع داده‌های خود است. مثلا برای رشته‌ها هیچ محدودیتی را در نظر نمی‌گیرند. شاید در سمت کلاینت اینکار را انجام می‌دهند؛ ولی نکته‌ی مهم در طرف دیتابیس است که چگونه تعریف می‌شود. در این حالت (nvarchar(MAX در نظر گرفته میشود که به معنی اشاره به منطقه دوگیگابایتی از اطلاعات است. در نکات بعدی، قصد داریم این مرحله را یک گام به جلوتر پیش ببریم و آن هم ایجاد نوع داده‌های بهینه‌تر در Sql Server است.

نکته مهم: بدیهی است که تغییرات زیر، ORM شما را تنها به sql server مقید می‌کند که بعدها در صورت تغییر دیتابیس نیاز به حذف موارد زیر را خواهید داشت؛ در غیر اینصورت به مشکل عدم ایجاد دیتابیس برخواهید خورد.

اولین مورد مهم بحث تاریخ و زمان است؛ وقتی ما یک نوع داده را تنها DateTime در نظر بگیریم، در Sql Server هم همین نوع داده وجود دارد و انتخاب میشود. ولی اگر شما واقعا نیازی به این نوع داده نداشته باشید چطور؟ در حال حاضر من بر روی یک برنامه‌ی کارخانه کار میکنم که بخش کارمندان و گارگران آن سه داده زمانی زیر را شامل می‌شود:
        public DateTime BirthDate { get; set; }
        public DateTime HireDate { get; set; }
        public DateTime? LeaveDate { get; set; }

حال به جدول زیر نگاه کنید که هر نوع داده چه مقدار فضا را به خود اختصاص می‌دهد:
  SmallDateTime   4 بایت
  DateTime  8 بایت
  DateTime2  6 تا 8 بایت
  DateTimeOffset   8 تا 10 بایت
  Date  3 بایت
  Time  3 تا 5 بایت

از این جدول چه می‌فهمید؟ با یک نگاه می‌توان فهمید که ساختار بالای من باید 24 بایت گرفته باشد؛ برای ساختاری که هم تاریخ و هم زمان (ساعت) را پشتیبانی می‌کند. ولی با نگاه دقیق‌تر به نام پراپرتی‌ها این نکته روشن می‌شود که ما یک گپ Gap (فضای بیهوده) داریم چون زمان تولد، استخدام و ترک سازمان اصلا نیازی به ساعت ندارند و همان تاریخ کافی است. یعنی نوع Date با حجم کلی 9 بایت؛ که در نتیجه 15 بایت صرفه جویی در یک رکورد صورت خواهد گرفت.

پس کد بالا را به شکل زیر تغییر می‌دهم:

          [Column(TypeName = "date")]
        public DateTime BirthDate { get; set; }

        [Column(TypeName = "date")]
        public DateTime HireDate { get; set; }

        [Column(TypeName = "date")]
        public DateTime? LeaveDate { get; set; }
خصوصیت Column از نسخه 4.5دات نت فریم ورک اضافه شده و در فضای نام System.ComponentModel.DataAnnotations.Schema قرار گرفته است.
نوع‌هایی که در بالا با سایز متغیر هستند، به نسبت دقتی که برای آن تعیین می‌کنید، سایز می‌گیرند. مثل (time(0 که 3 بایت از حافظه را می‌گیرد. در صورتی که time معرفی کنید، به جای اینکه از شیء DateTime استفاده کنید، از شی Timespan استفاده کنید، تا در پشت صحنه از نوع داده time استفاده کند. در این حالت حداکثر حافظه یعنی 5 بایت را برخواهد داشت و بهترین حالت ممکن این هست که نیاز خود را بسنجید و خودتان دقت آن را مشخص کنید. دو شکل زیر نحوه‌ی تعریف نوع زمان را مشخص می‌کنند. یکی حالت پیش فرض و دیگری انتخاب دقت:
     public class Testtypes
    {
           public TimeSpan CloseTime { get; set; }
            public TimeSpan CloseTime2 { get; set; }
    }
   public class TestConfig : EntityTypeConfiguration<Testtypes>
    {
        public TestConfig()
        {
            this.Property(x => x.CloseTime2).HasPrecision(3);
        }
    }
در تکه کد بالا همه از نوع time تعریف می‌شوند ولی در خصوصیت شماره یک نهایت استفاده از نوع تایم یعنی (time(7 مشخص می‌شود. ولی در خصوصیت بعدی چون در کانفیگ دقت آن را مشخص کرده‌ایم از نوع (time(3 تعریف می‌شود.

مورد دوم در مورد داده‌های اعشاری است:
بسیاری از برنامه نویسان تا آنجا که دیده‌ام از نوع float و single و double برای اعداد اعشاری استفاده می‌کنند ولی باید دید که در آن سمت دیتابیس، برای این نوع داده‌ها چه اتفاقی می‌افتد. نوع float در دات نت، با نوع single برابری میکند؛ هر دو یک نام جدا دارند، ولی در واقع یکی هستند. عموما برنامه نویسان به طور کلی بیشتر از همان single استفاده می‌کنند و برای انتساب برای این دو نوع هم حتما باید حرف f را بعد از عدد نوشت:
float flExample=23.2f;
باید توجه کنید که اگر مثلا float انتخاب کردید، تصور نکنید که همان float در دیتابیس خواهد بود. این دو متفاوت هستند تبدیلات به شکل زیر رخ می‌دهد:
//real
public float FloatData { get; set; }
//real
public Single SingleData { get; set; }
//float
public double DoubleData { get; set; }
  همه نوع‌های بالا اعداد اعشاری هستند که به صورت تقریبی و به صورت نماد اعشاری ذخیره می‌گردند و برای به دست آوردن مقدار ذخیره شده، هیچ تضمینی نیست همان عددی که وارد شده است بازگردانده شود. اگر تا به حال در برنامه هایتان به چنین مشکلی برنخوردید دلیلش اعداد اعشاری کوچک بوده است. ولی با بزرگتر شدن عدد، این تفاوت به خوبی دیده می‌شود. 
حالا اگر بخواهیم اعداد اعشاری را به طور دقیق ذخیره کنیم، مجبور به استفاده از نوع decimal هستیم. در دات نت آنچنان محدودیتی بر سر استفاده‌ی از آن نداریم. ولی در سمت سرور داده‌ها بهتر هست برای آن تدابیری اندیشیده شود. هر عدد دسیمال از دقت و مقیاس تشکیل می‌شود. دقت آن تعداد ارقامی است که در عدد وجود دارد و مقیاس آن تعداد ارقام اعشاری است. به عنوان مثال عدد زیر دقتش 7 و مقیاسش 3 است:
4235.254
در صورتی که عدد اعشاری را به دسیمال نسبت دهیم باید حرف m را بعد از عدد وارد کنیم:
decimal d1=4545.112m;
برای اعداد صحیح نیازی نیست.
برای تعیین نوع دسیمال از  fluent api استفاده می‌کنیم:
modelBuilder.Entity<Class>().Property(object => object.property).HasPrecision(7, 3);
کد زیر برای خصوصیت شماره یک، دقت 18 و مقیاس 2 را در نظر می‌گیرد و دومین خصوصیت طبق آنچه که برایش تعریف کرده ایم دقت 7 و مقیاس 3 است:
     public class Testtypes
    {
        public Decimal Decimal1 { get; set; }
        public Decimal Decimal2 { get; set; }

     }

 public class TestConfig : EntityTypeConfiguration<Testtypes>
    {
        public TestConfig()
        {
            this.Property(x => x.Decimal2).HasPrecision(7, 3);
        }
    }

مورد سوم مبحث رشته هاست
:
کدهای زیر را مطالعه فرمایید:
[StringLength(25)]
public string FirstName { get; set; }

[StringLength(30)]
[Column(TypeName = "varchar")]
public string EnProductTitle { get; set; }


public string ArticleContent { get; set; }
[Column(TypeName = "varchar(max)")]
public string ArticleContentEn { get; set; }
اولین رشته بالا (نام) را به محدوده‌ای از کاراکترها محدود کرده‌ایم. به طور پیش فرض تمامی رشته‌ها به صورت nvarchar در نظر گرفته می‌شوند. بدین ترتیب در رشته نام کوچک (nvarchar(25 در نظر گرفته خواهد شد. حال اگر بخواهیم فقط حروف انگلیسی پشتیبانی شوند، مثلا نام فنی کالا را بخواهید وارد کنید، بهتر هست که نوع آن به طرز صحیحی تعریف شود که در کد بالا با استفاده از خصوصیت Column نوع varchar را معرفی می‌کنم. بدین ترتیب تعریف نهایی نوع به شکل (varchar(30 خواهد بود. استفاده از fluentApi‌ها هم در این رابطه به شکل زیر است:
this.Property(e => e.EnProductTitle).HasColumnType("VARCHAR").HasMaxLength(30);
برای مواردی که محدوده‌ای تعریف نشود (nvarchar(MAX در نظر گرفته میشود مانند پراپرتی ArticleContent بالا. ولی اگر قصد دارید فقط حروف اسکی پشتیبانی گردند، مثلا متن انگلیسی مقاله را نیز نگه می‌دارید بهتر هست که نوع آن بهیته‌ترین حالت در نظر گرفته شود که برای پراپرتی ArticleContentEn نوع (varchar(MAX تعریف کرده‌ایم. 
همانطور که گفتیم پیش فرض رشته‌ها nvarchar است، در صورتی که دوست دارید این پیش فرض را تغییر دهید روش زیر را دنبال کنید:
modelBuilder.Properties<string>().Configure(c => c.HasColumnType("varchar"));


//=========== یا

modelBuilder.Properties<string>().Configure(c => c.IsUnicode(false));


جهت تکمیل بحث نیز هر کدام از متغیرهای عددی در سی شارپ معادل نوع‌های زیر در Sql Server هستند:
//tinyInt
public byte Age { get; set; }

//smallInt
public Int16 OldInt { get; set; }

//int
public int Int32 { get; set; }

//Bigint
public Int64 HighNumbers { get; set; }

مطالب دوره‌ها
حلقه های تکرار
در #F سه نوع حلقه تکرار وجود دارد. مفهوم حلقه‌های تکرار در #F مانند سایر زبان‌های برنامه نویسی است. در این جا فقط به syntax و نوع کد نویسی اشاره خواهیم داشت.
انواع حلقه‌های تکرار
  • حلقه تکرار for in
  • حلقه تکرار for to
  • حلقه تکرار while do

در ادامه به بررسی و پیاده سازی مثال برای هر سه حلقه می‌پردازیم 

#1 حلقه for ساده
let list1 = [ 1; 5; 100; 450; 788 ]
for i in list1 do
   printfn "%d" i
خروجی:
1
5
100
450
788
#2حلقه for با تعداد پرش دو( 1 تا 10 با تعداد پرش 2 )
  for i in 1 .. 2 .. 10 do
     printf "%d " i
خروجی
1 3 5 7 9
 #3 حلقه for با استفاده از محدوده کاراکتر ها
  for c in 'a' .. 'z' do
    printf "%c " c
خروجی
a b c d e f g h i j k l m n o p q r s t u v w x y z
#4 حلقه for به صورت شمارش معکوس
   for i in 10 .. -1 .. 1 do
        printf "%d " i
خروجی :
10 9 8 7 6 5 4 3 2 1
  #5حلقه for که شروع و اتمام محدوده آن به صورت عبارت است.

let beginning x y = x - 2*y
let ending x y = x + 2*y

  for i in (beginning x y) .. (ending x y) do
     printf "%d " i
خروجی مثال بالا با ورودی‌های 10 و 4 به صورت زیر خواهد بود
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#6 حلقه for to
for i = 1 to 10 do
    printf "%d " i
خروجی
1 2 3 4 5 6 7 8 9 10
#7 حلقه for to به صورت شمارش معکوس
for i = 10 downto 1 do
    printf "%d " i
خروجی
10 9 8 7 6 5 4 3 2 1
#8 حلقه for to  با استفاده از محدوده شروع و اتمام به صورت عبارت
 for i = (beginning x y) to (ending x y) do
     printf "%d " i
خروجی مثال بالا برای ورودی‌های 10 و 4 به صورت زیر است
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

#9 حلقه while do
ساختار کلی آن به صورت زیر است.
while test-expression do
   body-expression
#10مثال کامل از حلقه while do
open System
 
let main() =
    let password = "monkey"//شناسه برای مقدار رمز عبور
    let mutable guess = String.Empty// شناسه برای حدس رمز عبور
    let mutable attempts = 0//تعداد دفعات تست
 
    while password <> guess && attempts < 3 do// تا زمانی که رمز عبور با حدس آن برابر نیست و تعداد دفعات تکرار کمتر از سه است
        Console.Write("What's the password? ")//چاپ پیغام در خروجی
        attempts <- attempts + 1//مقدار دفعات یکی افزایش می‌یابد
        guess <- Console.ReadLine()// حدس رمز عبور از ورودی دریافت می‌شود
 
    if password = guess then// اگر رمز عبور با حدس آن یکی بود
        Console.WriteLine("You got the password right!")// پیغام موفقیت
    else
        Console.WriteLine("You didn't guess the password")//پیغام عدم موفقیت
 
    Console.ReadKey(true) |> ignore//منتظر ورودی برای خروج از برنامه
تنها نکته قابل ذکر در مثال بالا استفاده از mutable keyword برای تعریف شناسه attempts است. (طبق توضیحات فصل قبل) به دلیل اینکه تعداد دفعات تکرار برای ما مهم است و نمی‌خواهیم در هر محدوده این مقدار به حالت قبلی خود بازگردد از mutable استفاده کردیم.
نظرات مطالب
Portable Class Library چیست و چگونه از آن استفاده کنیم؟
علاقه ای به طولانی کردن بحث ندارم، لکن
در مورد این قسمت " مابقی مواردی که در این کتابخانه پرتابل قابل استفاده نیست خوب به روش معمول استفاده خواهند شد "، بیایم و با مثال صحبت کنیم
ما فرضا می‌آییم و View Model رو با Portable Class Library می‌زنیم، سپس، می‌آییم و یک پروژه Silverlight ای و WPF ای و اندرویدی قرار می‌دهیم و از View Model مربوطه استفاده می‌کنیم ( از این که View Model مربوطه رو می‌خواهیم در اندروید هم استفاده کنیم و در این صورت از کدام حالت Portable Class Library بگذریم )، حال اگر بخواهیم از فریم ورک X که در هر 3 هست و خط کد یکسانی داره استفاده کنیم، باید اون رو به کدوم پروژه اضافه کنیم تا به این جمله برسیم ؟ مابقی مواردی که در این کتابخانه پرتابل قابل استفاده نیست خوب به روش معمول استفاده خواهند شد " ، ممنون می‌شوم مثالی ارائه دهید، چون من واقعا به این آیتم احتیاج دارم تا بتونم استفاده از Portable‌ها رو به صورت جدی شروع کنم.
زمانی که در پروژه اصلی ( که بقیه پروژه‌ها از روی آن Add As Link شده اند )، متدی رو Rename می‌کنیم در خود اون پروژه که عمل Refactor انجام می‌شه، به سادگی، بقیه پروژه که از خودشون چیزی ندارند، و به پروژه اصلی فقط Shortcut دارند، عملا اونها هم Refactor شده هستند.
اشکال This document is opened by رو قبول دارم، ولی اگه شما مبحث هزینه فایده رو قبول داشته باشید، به نظر من این هزینه کوچک به فایده اش واقعا می‌ارزه، مگه این که شما بفرمایید سناریوی آندروید، WPF و Silverlight و کتابخانه‌های مشترک شون رو چه جوری با Portable حل می‌کنید، اون وقت روش Portable فایده اش بیشتره، من که از Portable بدم نمی‌آد، از خدام هستش که همه چی در یه پروژه باشه تا 3 تا پروژه 
در مورد Intelliscne بله، این امکان داره، ولی من ترجیح می‌دم به جای این که کور کورانه محدود بشم، و نتونم از کدی که مطمئنم در WPF و Silverlight و اندروید به یک شکل هست نتونم استفاده کنم، چون فقط در Portable Library دیده نشده، ترجیح می‌دم 1% به اندازه 5 خط کد اشتباه بنویسم، که کامپایلر 2 دقیقه بعد خطاش رو ساده و واضح بهم می‌گه
مورد آخر جمله‌ی کلی است و قابلیت نقد و بررسی را ندارد.
موفق باشید