نظرات مطالب
EF Code First #12
سلام آقای نصیری من در حال نوشتن یک پروژه ویندوزی با روشهای گفته شده در این سایت هستم، منظور استفاده از EF Code First و StructureMap و ... می‌باشد. Base برنامه نوشته شده و شامل یک پروژه مرکزی- پروژه حسابداری مالی – حقوق دستمزد- خرید وفروش و.... می‌باشد، کاربران فقط و فقط از طریق اجرای سیستم مرکزی قادر به ورود به سیستم‌های نرم افزاری حوزه خود می‌باشند، با توجه به مطالب فوق الذکر و پرسش و پاسخ‌های کلیه دوستان، متوجه شدم که فقط باید از یک Context استفاده کرد، درسته؟ در حالیکه از بین این چند نرم افزار شاید شرکتی تنها قصد خرید واستفاده سیستم مالی وشرکتی دیگر سیستم مالی وn تای دیگر از برنامه‌ها رو خرید و مورد استفاده قرار دهد، و چون فعلا کلیه عملیات مرتبط با بانک اطلاعاتی در یک Context ودر MainProject انجام میشه، شرکتی که از یک نرم افزار من استفاده خواهد کرد همان ساختار جداول و بانک اطلاعاتی را دارد که شرکتی دیگر از چند نرم افزار دیگر از همین پروژه استفاده میکند. درکل نکته مبهم برام اینست که با چه تکنیک و روشی می‌توان از uow استفاده و پیروی کرد ولی هر پروژه Context خودش رو داشته باشد که با ورود به آن زیرسیستم، عملیات ساخت یا ویرایش DataBase و جداول مرتبط فقط بر روی آن زیر سیستم انجام شود و هیچ تاثیری رو جداول سیستم‌های دیگر نداشته باشد؟ (درضمن کلیه سیستم‌های از یک DataBase استفاده خواهند کرد). با تشکر
نظرات مطالب
پایان پروژه ASP.NET Ajax Control Toolkit !
مایکروسافت ASP.NET Ajax را با اون عظمت و زحمتی که براش کشیده بودند، در مقابل jQuery بازنده اعلام کرده الان شما صحبت از Anthem.Net می‌کنید که فقط منحصر است به ASP.NET web forms آن هم نگارش‌های قبل از سه آن + پشتیبانی از مرورگرهای مختلف هم در آن ضعیف است.
هدف مایکروسافت از اینکار مدیریت هر دو پروژه MVC و Web forms است آن هم با هزینه کم، کیفیت بالا و سازگار با تمام مرورگرها.
ضمنا این رو در نظر باشید که یکی از توانمندی‌های jQuery، Ajax است (از کار با DOM گرفته تا دستکاری CSS نمایش داده شده، تا Animation ، مدیریت ساده‌تر رخدادها، اعمال قالب به سایت و غیره) و این مورد مزیت مهمی است نسبت به تمام کتابخانه‌هایی که فقط برای یک کار و آن هم سهولت تولید برنامه‌های مبتنی بر Ajax ایجاد شده‌اند و از چند مشکل مهم رنج می‌برند:
- تک کاره‌اند. فقط Ajax .
- مشکل سازگاری با مرورگرهای مختلف را دارند.
- به صورت فعال توسعه داده نمی‌شوند؛ رفع باگ نمی‌شوند و غیره. برای مثال فواصل به روز رسانی همان Anthem.Net را بررسی کنید.
- توسعه پذیر نیستند. برای مثال آیا می‌توان برای Anthem.Net افزونه نوشت؟
- حجم بالایی دارند.
- سرعت پایینی دارند.

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

و RAD هزینه بر است. یعنی چی؟ یعنی حجم بالای کدهای اسکریپتی که باید به برنامه‌ی شما مثلا توسط ASP.NET Ajax تزریق شود که مبادا شما بخواهید دست خودتان را به نوشتن چند سطر کد جاوا اسکریپتی آلوده کنید. همچنین حجم تبادل اطلاعات ASP.NET Ajax را هم که مبتنی است بر RAD را هم با حجم اطلاعات مبادله شده توسط jQuery مقایسه کنید (با پلاگین فایرباگ مربوط به فایرفاکس). این حجم واقعا زیاد است و قابل مقایسه نیست. (تمام این‌ها هزینه‌های RAD است)
ضمنا وجود 100 ها افزونه و پلاگین نوشته شده برای jQuery کار شما را بسیار بسیار ساده می‌کنند، مانند پاسخ قبلی من در این مطلب.
فقط باید کمی وقت بگذارید و چیزی را بیاموزید که واقعا ارزش دارد. گیرم فردا نخواستید با ASP.NET کار کنید. تمام این اطلاعات در PHP هم به درد شما می‌خورد، چون قسمت سمت کلاینت آنچنان تفاوتی نمی‌کند و jQuery یک کتابخانه‌ی سمت کلاینت است.
مطالب
آموزش WAF (بررسی Commandها)
در این پست قصد داریم مثال  قسمت قبل را توسعه داده و پیاده سازی Command‌ها را در آن در طی یک مثال بررسی کنیم. از این جهت دکمه‌ای، جهت حذف آیتم انتخاب شده در دیتا گرید، به فرم BookShell اضافه می‌نماییم. به صورت زیر:
<Button Content="RemoveItem" Command="{Binding RemoveItemCommand}" HorizontalAlignment="Left"  VerticalAlignment="Top" Width="75"/>
Command تعریف شده در Button مورد نظر به خاصیتی به نام RemoveItemCommand در BookViewModel که نوع آن ICommand است اشاره می‌کند. پس باید تغییرات زیر را در ViewModel اعمال کنیم:
public ICommand RemoveItemCommand { get; set; }
از طرفی نیاز به خاصیتی داریم که به آیتم جاری در دیتاگرید اشاره کند.
  public Book CurrentItem 
        {
            get
            {
                return currentItem;
            }
            set
            {
                if(currentItem != value)
                {
                    currentItem = value;
                    RaisePropertyChanged("CurrentItem");
                }
            }
        }
        private Book currentItem;

همان طور که در پست قبلی توضیح داده شد پیاده سازی‌ها تعاریف ViewModel در Controller انجام می‌گیرد برای همین منظور باید تعریف DelegateCommand که یک پیاده سازی خاص از ICommand است در کنترلر انجام شود. :
 [Export]
    public class BookController
    {
        [ImportingConstructor]
        public BookController(BookViewModel viewModel)
        {
            ViewModelCore = viewModel;
        }

        public BookViewModel ViewModelCore
        {
            get;
            private set;
        }

        public DelegateCommand RemoveItemCommand 
        { 
            get; 
            private set;
        }

        private void ExecuteRemoveItemCommand()
        {
            ViewModelCore.Books.Remove(ViewModelCore.CurrentItem);
        }

        private void Initialize()
        {
            RemoveItemCommand = new DelegateCommand(ExecuteRemoveItemCommand);
            ViewModelCore.RemoveItemCommand = RemoveItemCommand;
        }

        public void Run()
        {

            var result = new List<Book>();
            result.Add(new Book { Code = 1, Title = "Book1" });
            result.Add(new Book { Code = 2, Title = "Book2" });
            result.Add(new Book { Code = 3, Title = "Book3" });

            Initialize();

            ViewModelCore.Books = new ObservableCollection<Models.Book>(result);        

            (ViewModelCore.View as IBookView).Show();
        }              
    }

تغییرات:
»خاصیتی به نام RemoveItemCommand که از نوع DelegateCommand است تعریف شده است؛
»متدی به نام Initialize اضافه شد که متد‌های Execute و CanExecute برای Command‌ها را در این قسمت رجیستر می‌کنیم.
»در نهایت Command تعریف شده در کنترلر به Command مربوطه در ViewModel انتساب داده شد.

حال کافیست خاصیت SelectedItem دیتاگرید BookShell به خاصیت CurrentItem موجود در ViewModel مقید شود:
 <DataGrid ItemsSource="{Binding Books}" SelectedItem="{Binding CurrentItem ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="400" Height="200">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Code" Binding="{Binding Code}" Width="100"></DataGridTextColumn>
                <DataGridTextColumn Header="Title" Binding="{Binding Title}" Width="300"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
اگر پروژه را اجرا نمایید، بعد از انتخاب سطر مورد نظر و کلیک بر روی دکمه RemoveItem مورد زیر قابل مشاهده است:

مطالب
نحوه استفاده از Text template ها در دات نت - قسمت چهارم
در قسمت‌های قبلی (^ و ^ و ^) با Text Template در Visual Studio آشنا شدید. این قسمت برای تکمیل بحث در مورد ابزاری که Microsoft از آن در برنامه‌های خود از جمله Visual Studio جهت تولید کدهای اتوماتیک استفاده می‌نماید، صحبت خواهیم کرد.
قبل از آن بد نیست که بدانید چرا این ابزار T4  نام گرفته !
T4 مخفف  Text Template Transformation Toolkit می‌باشد (TTTT). شکل زیر مراحل اجرای یک کد Text Template را توسط T4 نشان میدهد: 


پس این ابراز، یک ابزار کاربردی می‌باشد که بدون Visual Studio نیز میتوان از آن استفاده کرد. نام فایل این ابزار، TextTransform.exe است و در مسیر زیر وجود دارد :

Program Files (x86)\Common Files\microsoft shared\TextTemplating\10.0
برای اطلاع از نحوه کار با TextTransform.exe خارج از محیط Visual Studio بهتر است دستور زیر را در cmd.exe اجرا کنید تا راهنمای استفاده و پارامتر‌های اختیاری آن را مشاهده نمایید:

  TextTransform.exe –h 

برای آزمایش، یک فایل متنی کنار فایل TextTransform.exe با نام Text2.tt ایجاد نمایید و کد زیر را در داخل آن بنویسید:
<#@ template debug="true" hostspecific="false" language="C#" #>
<#@ output extension=".txt"  #>

<#@ import namespace="System.Diagnostics" #>

Report In : <#= DateTime.Now #>

<#

Process[] Procs = Process.GetProcesses();
    for (int i = 0; i < Procs.Length; i++)
    {
        string Pstr = Procs[i].ProcessName + "  -|-  " + Procs[i].Id + Environment.NewLine ;
 #><#= Pstr #><#
    }

#>
 این مثال بعد از اجرا، لیست تمام Process های جاری سیستم را به همراه Id  آن‌ها، چاپ می‌نماید.
برای تولید فایل خروجی، دستور زیر را در cmd.exe اجرا کنید :
TextTransform.exe  -out  Report1.txt  Text2.tt
توجه کنید که فایل Text2.tt را کنار فایل TextTransform.exe قرار دهید و بعد از اجرای دستور بالا، باید خروجی در فایل Text2.tt در همان مسیر ایجاد گردد.

نکته: اگر User شما به این پوشه دسترسی ندارد و کاربر Admin نیستید احتمالا به مشکل بر می‌خورد. می‌توانید فایل TextTransform.exe را در مکان دیگری قرار دهید و دستور را از آن محل اجرا کنید و یا برای پوشه‌ی مذکور دسترسی ایجاد نمایید.

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

http://www.olegsych.com/2008/05/t4-architecture/

نکته دیگر این که برای Visual Studio، ابزارهایی جهت بهبود کار با Text Template‌ها وجود دارند که با جستجوی T4 Editor، نمونه‌هایی از آنها را خواهید یافت. tangible T4 Editor نمونه ای از این Pluginها می‌باشد که به Visual Studio  افزوده می‌گردد و یا یک پروژه Open Source  هم برای آشنایی بسیار بیشتر با T4 در t4toolbox.codeplex.com وجود دارد که میتوانید مشاهده کنید.
مطالب
آشنایی با Window Function ها در SQL Server بخش پنجم
در این بخش فانکشن د‌یگری از توابع تحلیلی به نام CUME_DIST را بررسی می‌نماییم.
  •      CUME_DIST: 
      بوسیله تابع CUME_DIST می‌توان ارزیابی نمود، در یک گروه، چه درصد از مقادیر،مساوی یا کوچکتر از مقدار سطر جاری می‌باشند، به این تابع cumulative distribution نیز گفته می‌شود.
   Syntax تابع CUME_DIST به صورت زیر است:
CUME_DIST( )
    OVER ( [ partition_by_clause ] order_by_clause )
شرح Syntax:
1- Partition By Clause : بوسیله پارامتر فوق می‌توانید، نتیجه پرس جو (Query)،خود را دسته بندی نمایید.
2- order by clause : همانطور که از نامش مشخص است، جهت مرتب نمودن خروجی Query می‌باشد.
معمولا شرح عملکرد توابع تحلیلی، کمی مشکل است. بنابراین برای درک، عملکرد تابع CUME_DIST چند مثال را بررسی می‌کنیم.
در ابتدا بوسیله Script زیر یک جدول ایجاد و 10 رکورد در آن درج می‌کنیم:
Create Table TestCUME_DIST
(SalesOrderID int not null,
OrderQty smallint not null,
ProductID int not null
 );
 GO
Insert Into TestCUME_DIST
       Values (43663,1,760),(43667,3,710),(43667,1,773),
  (43667,1,775),(43667,1,778),(43669,1,747),
  (43670,1,709),(43670,2,710),(43670,2,773),(43670,1,776)

مثال اول: Script زیر را اجرا می‌کنیم، سپس خروجی آن را بررسی می‌نماییم:
SELECT SalesOrderID, OrderQty,
       CUME_DIST() OVER(ORDER BY SalesOrderID) AS [CUME_DIST]
FROM TestCUME_DIST ORDER BY [CUME_DIST] DESC
پس از اجرا خروجی بصورت زیر خواهد بود:

در ادامه اجازه دهید،مقادیری که در فیلد CUME_DIST بدست آمده است را بصورت تصویری بررسی کنیم.
مقادیر سطر اول تا چهارم:

*** برای بدست آوردن CUME_DIST سطر پنجم نیز خواهیم داشت:

Rows=(c1+c2)/c3 بنابراین خواهیم داشت: 0/6=10/(5+1)=Rows

مثال دوم : ابتدا Script زیر را اجرا نمایید:

SELECT SalesOrderID, OrderQty, ProductID,
       CUME_DIST() OVER(PARTITION BY SalesOrderID ORDER BY ProductID ) AS [CUME_DIST]
FROM TestCUME_DIST
WHERE SalesOrderID IN (43670, 43669, 43667, 43663)
ORDER BY SalesOrderID DESC, [CUME_DIST] DESC
خروجی : 

   همانگونه که ملاحظه می‌کنید، در این مثال، خروجی، براساس SalesOrderID به چهار گروه تقسیم می‌شود و عملیات مرتب سازی روی فیلد ProductID انجام  می گیرد، بنابراین CUME_DIST، روی هر گروه بر روی فیلد ProductID محاسبه می‌شود.

گروه اول : نحوه محاسبه Cume_DIST سطر اول:

سوال:چه تعداد از مقادیر ProductID آن برابر 776 میباشد؟

جواب: فقط مقدار سطر اول، بنابراین خواهیم داشت                   C1=1

سوال: چه تعداد از مقادیر کوچکتر از ProductID=776 می‌باشد؟

جواب: مقدار سه سطر، در واقع مقادیر سطر دوم،سوم و چهارم کوچکتر از مقدار سطر اول می‌باشند،                          c2=3

سوال: تعداد کل سطرهای گروه اول چه مقدار می‌باشد؟

جواب: 4سطر 

بنابراین برای بدست آوردن CUME_DIST سطر اول خواهیم داشت:

1=4/(1+3)=Rows 

محاسبه سطر دوم از گروه اول بدون شرح:

0/75=4/(1+2)=Rows  

امیدوارم مفید واقع شده باشد.

اشتراک‌ها
اندازه گیری دما، مختصات جغرافیایی، لرزه یا تکانه و تنظیم نمودن هشدار دهنده توسط NET Micro Framework
اگر شما یک دات نت developer هستید، می‌توانید بدون داشتن دانش زبانهای سطح پایین مانند Assembly روی دستگاههای سازگار با این فریم ورک کد بنویسید و شرایط محیطی پیرامونتان را مانیتور نمایید. این پلت فرم رایگان و با سورس باز است و فرصت طلایی را در اختیار توسعه دهندگان جهت برنامه نویسی روی میکرو پروسسورها "با حداقل تنظیمات پیچیده" قرار می‌دهد. 
شما می‌توانید با syntax (دستورات) دات نتی روی بوردهایی با قیمت زیر 100$ براحتی در محیط دات نت برنامه بنویسید و به همان راحتی باگ گیری نمایید. بعنوان مثال برنامه GPS را روی بورد بنویسید و آن را به شی نصب کرده و از مختصات جغرافیایی در هر لحظه آگاه شوید. و یا دمای پیرامونتان را هر از X ثانیه توسط Thread اندازهگیری نمایید و چنانچه بالاتر و یا پایین‌تر از مقدار مورد انتظارتان بود هشدار دهنده را فعال نمایید.

Measuring temperature, GPS, vibration and set alarms by NET Micro Framework

اندازه گیری دما، مختصات جغرافیایی، لرزه یا تکانه و تنظیم نمودن هشدار دهنده توسط NET Micro Framework
نظرات مطالب
جلوگیری از ارسال Spam در ASP.NET MVC
با تشکر از شما. چند نکته از لاگ‌های استخراج شده‌ی سایت جاری:
- این برنامه‌ها، user agent‌های متفاوتی را به ازای هر درخواست ارسال می‌کنند (عموما). بنابراین مورد دوم هم علاوه بر مورد سوم نباید بکار گرفته شود.
- دو نوع هش در حالت کلی وجود دارند. هش‌های سریع و هش‌های امن. هش‌های امن سعی می‌کنند این تضمین را ارائه دهند که به ازای یک ورودی مشخص، خروجی منحصربفردی را تولید کنند؛ اما ... با قیمت کندتر بودن عملیات هش. هش‌های سریع، مانند xxHash، برای یک چنین مواردی که نیاز هست کلید کش تولید شود بکار گرفته می‌شوند. الزاما مانند هش‌های امن سعی در تولید خروجی‌های منحصربفردی نمی‌کنند، اما تا این اندازه دقیق هستند که در بانک‌های اطلاعاتی key-value store فوق سریعی مانند Redis از آن‌ها استفاده می‌شود. بنابراین در یک چنین مواردی مانند سناریوی جاری بهتر است از هش‌های سریع استفاده شود. البته اگر آدرس صفحه و همچنین UA را حذف کنیم، نیازی به هش کردن نخواهد بود؛ چون IP را می‌توان بعنوان کلید درنظر گرفت.
- بررسی UA از دیدگاه دیگری به صورت جداگانه می‌تواند مفید باشد. تشخیص بات‌های شناخته شده و بستن دسترسی آن‌ها.
مطالب
بررسی الگوی Visitor در جاوا اسکریپت
این الگو اجازه‌ی تعریف کردن عملیاتی جدید را برای مجموعه‌ای از شیء‌ها، بدون تغیر دادن ساختار خود شیء‌ها، میدهد. همچنین اجازه‌ی جدا کردن کلاس را از منطقی که کلاس  پیاده سازی می‌کند، به ما میدهد.
عملیات بیشتری می‌توانند در شیء Visitor کپسوله سازی شوند. شیء‌ها می‌توانند یک متد visit داشته باشند که یک شیء Visitor را دریافت می‌کند. Visitor می‌تواند تغییرات مورد نیاز را ایجاد کند و عملیاتی را بر روی شیء‌هایی که دریافت کرده‌است، انجام دهد.

این الگو به توسعه دهندگان این اجازه را میدهد که کتابخانه‌ها (libraries)، فریم ورک‌ها (frameworks) و ... را گسترش دهند.


مثال: 

class Visitor {
    visit(item){}
}

class BookVisitor extends Visitor {
    visit(book) {
        var cost=0; 
        if(book.getPrice() > 50) 
        { 
            cost = book.getPrice()*0.50 
        } 
        else{
            cost = book.getPrice()
        }     
        console.log("Book name: "+ book.getName() + "\n" + "ID: " + book.getID() + "\n" + "cost: "+ cost); 
        return cost; 
    }
}

class Book{
    constructor(id,name,price){
        this.id = id
        this.name = name
        this.price = price
    }
    getPrice(){
        return this.price
    }
    getName(){
        return this.name
    }
    getID(){
        return this.id
    }
    accept(visitor){
        return visitor.visit(this)
    }
}

var visitor = new BookVisitor()
var book1 = new Book("#1234","lordOftheRings",80)
book1.accept(visitor)

در مثال بالا ما یک کتابفروشی داریم. کلاس Book برای نشان دادن یک کتاب در فروشگاه استفاده شده‌است. این کلاس همانند زیر تعریف شده‌است: 
class Book{
    constructor(id,name,price){
        this.id = id
        this.name = name
        this.price = price
    }
    //code...
}

یک کتاب خصوصیات زیر را دارد: 
  • id
  • name
  • price

هم چنین شامل توابع زیر می‌باشد:
getPrice(){
    return this.price
}

getName(){
    return this.name
}

getID(){
    return this.id
}

متد getPrice ، قیمت را برگشت میدهد، getName ، نام را برگشت میدهد و getID، شناسه‌ی کتاب را برگشت میدهد.

اکنون کتابفروشی یک تخفیف را برای کتاب‌هایی که هزینه‌ی آن‌ها بیشتر از 50 دلار است، معرفی می‌کند. در ادامه، می‌خواهیم یک عملیات دیگر را انجام دهیم و تخفیف را بر روی آن‌ها پیاده سازی کنیم. در اینجا از الگوی visitor استفاده خواهیم کرد. ما یک Visitor را معرفی می‌کنیم که کتابها را بازدید خواهد کرد و قیمت آن‌ها را به‌روزرسانی می‌کند. بنابراین شیء‌های کتاب باید تابعی داشته باشند که اجازه دهد visitor، آنها را بازدید (visit) کند و عملیات مد نظر را بر روی آن‌ها انجام دهد. برای این منظور، یک متد به نام accept  در کلاس Book  تعریف کرده‌ایم:
 
accept(visitor){
    return visitor.visit(this)
}

متد accept  یک شیء visitor را به عنوان یک آرگومان دریافت می‌کند و به آن اجازه میدهد که با فراخوانی کردن تابع visit خودش، کتاب جاری را بازدید (visit) کند (this اشاره به کتاب جاری دارد) .

اکنون اجازه دهید نگاهی به کلاس Visitor  داشته باشیم: 
class Visitor {
   visit(item){}
}

این کلاس، یک تابع به نام visit دارد و itemی را که می‌خواهد بازدید (visit ) کند، به عنوان پارامتر دریافت می‌کند. در این سناریو، می‌خواهیم که کتاب‌ها را بازدید (visit ) کنیم. از این رو، در ابتدا یک کلاس را به نام BookVisitor تعریف می‌کنیم که کلاس Visitor را extend می‌کند: 

class BookVisitor extends Visitor {
   visit(book) {
      var cost=0; 
      if(book.getPrice() > 50) 
      { 
         cost = book.getPrice()*0.50 
      } 
      else{
         cost = book.getPrice()
      }     
      console.log("Book name: "+ book.getName() + "\n" + "ID: " + book.getID() + "\n" + "cost: "+ cost); 
      return cost; 
   }
}

تابع visit، قیمت کتابی را که دارد بازدید می‌کند، بررسی می‌کند. اگر بزرگتر از 50 باشد، 50 درصد تخفیف را بر روی آن اعمال می‌کند؛ در غیر این صورت، قیمت به حالت قبلی خودش باقی می‌ماند. 

چه زمانی از این الگو استفاده کنیم:

  1. زمانیکه نیاز است عملیاتی مشابه، بر روی شیء‌های متفاوتی از یک data structure  انجام شود. 
  2. زمانیکه نیاز است عملیاتی خاص، بر روی شیء‌های متفاوتی از data structure انجام شود. 
  3. زمانیکه می‌خواهید توسعه پذیری را برای کتابخانه‌ها (libraries) یا فریم ورک‌ها (frameworks) اضافه کنید.