مطالب
لیستی از بانک‌های اطلاعاتی قابل استفاده در دات نت

بد نیست لیست تعدادی از بانک‌های اطلاعاتی مهم قابل استفاده در دات نت به همراه درایورهای ADO.NET آن‌ها را با هم مرور نمائیم.

بانک‌های اطلاعاتی قابل استفاده در دات نت فریم ورک

ردیف
بانک اطلاعاتی سایت مرجع درایور ADO.NET امکان استفاده از LINQ مجوز استفاده
توضیحات
1 SQL Server 2000/2005/2008/2008 R2 + توکار (به صورت پیش فرض در دات نت فریم ورک موجود است) بلی . به کمک LINQ to SQL ،
Entity Framework ، NHibernate و بسیاری از ORM های دیگر
رایگان - تجاری نسخه‌‌های Express آن رایگان است.
2 Microsoft SQL Azure + بلی :
+
بلی. به کمک LINQ to SQL و
Entity Framework
تجاری
3 SQL Server Compact + بلی :

+
بلی. به کمک LINQ to SQL و
Entity Framework
رایگان
4 Advantage Database Server
+
قابل دریافت از سایت اصلی:

+
بلی. به کمک Entity framework و
Telerik OpenAccess
ORM
تجاری
5 SQL Anywhere
+
قابل دریافت از سایت اصلی:
+
بلی. به کمک Entity framework
و Telerik
OpenAccess ORM
رایگان - تجاری
Web Edition
آن رایگان است.
6 MySQL + قابل دریافت از سایت اصلی :
+
بلی . به کمک
NHibernate
،
LightSpeed
، DbLinq و تعدادی دیگر از
ORM's
رایگان - تجاری
7 Oracle + پشتیبانی توکار آن به زودی
حذف
خواهد شد
اما از سایت اصلی قابل دریافت است :
+
بلی . به کمک
NHibernate
،
LightSpeed
، DbLinq و تعدادی دیگر از
ORM's
رایگان - تجاری نسخه‌ی Express آن رایگان است.
8 Access + توکار بلی. به کمک ALinq ،

NHibernate
و یا
LINQ to
DataSets
تجاری اگر از دات نت فریم ورک سه و نیم، سرویس پک یک استفاده کنید، امکان
استفاده از LINQ to SQL جهت کار با بانک‌های
اطلاعاتی اکسس نیز مهیا است:

+
9 SQLite + مهیا به صورت سورس باز :
+
بلی. درایور ADO.NET آن پشتیبانی از Entity
Framework را نیز اضافه می‌کند. همچنین NHibernate
،
ALinq
و سایر ORM's را باید به این لیست اضافه کرد.
رایگان
10 Firebird + قابل دریافت از سایت اصلی: ‌+ بلی. توسط ALinq ،
NHibernate
و موارد دیگر.
رایگان
11 PostgreSQL + قابل دریافت از سایت اصلی:
+
بلی. توسط NHibernate ، DBLinq و موارد دیگر رایگان
12 DB2 UDB + قابل دریافت از سایت اصلی:
+
بلی. توسط NHibernate تجاری
13 ScimoreDB + قابل دریافت از سایت اصلی:
+
محدود. توسط
LINQ to DataSets
رایگان
14 MongoDB + معرفی شده در سایت اصلی :
+
بلی. درایور ADO.NET معرفی شده به همراه
پروایدر LINQ نیز می‌باشد.
رایگان
15 CouchDB + معرفی شده در سایت اصلی :
+
محدود رایگان
16 VistaDB + اساسا برای دات نت نوشته شده است. بلی. به کمک
Entity framework
تجاری


بازخوردهای پروژه‌ها
خطا هنگام ایجاد هدر سفارشی با html
من میخواستم بااستفاده از html هدرم رو طراحی کنم ولی با خطاهای زیر روبرو میشم : 
[0] = {"Object reference not set to an instance of an object."}
[1] = {"The document has no pages."}

نمیدونم چون که نگارش پایین این کتابخانه رو استفاده میکنم این مشکل بوجود میاد یا نه؟
کدهای من :
PdfReport pdfrpt = new PdfReport();
                pdfrpt.DocumentPreferences(doc =>
                {
                    doc.RunDirection(PdfRunDirection.RightToLeft);
                    doc.Orientation(PageOrientation.Portrait);
                    doc.PageSize(PdfPageSize.A4);
                    doc.DocumentMetadata(new DocumentMetadata { Author = "Hovze", Application = "PdfRpt", Keywords = "Report", Subject = "Test Rpt", Title = "Report" });
                    doc.Compression(new CompressionSettings
                    {
                        EnableCompression = true,
                        EnableFullCompression = true
                    });
                    doc.PrintingPreferences(new PrintingPreferences
                    {
                        ShowPrintDialogAutomatically = true
                    });
                })
                .DefaultFonts(fonts =>
                {
                    fonts.Path(fontPath + "\\BNAZANIN.ttf", fontPath + "\\BNAZNNBD.ttf");
                    fonts.Size(13);
                })
                .PagesFooter(footer =>
                {
                    footer.DefaultFooter(PersianDate.ToPersianDateTime(DateTime.Now, "/", false, false));
                })
                .PagesHeader(header =>
                {
                    
                    header.HtmlHeader(rptheader =>
                    {
                        rptheader.PageHeaderProperties(new HeaderBasicProperties
                        {
                            RunDirection = PdfRunDirection.RightToLeft,
                            ShowBorder = true
                        });
                        rptheader.AddPageHeader(pageHeader =>
                        {
                            var message = "باسمه تعالی " + "</br>" + "حوزه علمیه امیر المومنین (ع) - معاونت آموزش - کارنامه تحصیلی طلبه";
                            var image = string.Format("<img src='{0}' />", imgPath);
                            return string.Format(@"<table style='width: 100%;font-size:9pt;font-family:BNAZANIN;'>
            <tr>
            <td align='center'>{0}</td>
            </tr>
            <tr>
            <td align='center'><b>{1}</b></td>
            </tr>
            <tr>
            <td align='center'>{2}</td>
            </tr>
                </table>", image, message, " تاریخ  " + PersianDate.ToPersianDateTime(DateTime.Now.Date, "/", false));
                        });

                    });
                })
                .MainTableTemplate(template =>
                {
                    template.BasicTemplate(BasicTemplate.SilverTemplate);
                })
                .MainTablePreferences(table =>
                {
                    table.ColumnsWidthsType(TableColumnWidthType.Relative);
                    table.NumberOfDataRowsPerPage(0);
                    table.GroupsPreferences(new GroupsPreferences
                    {
                        GroupType = GroupType.HideGroupingColumns,
                        RepeatHeaderRowPerGroup = true,
                        ShowOneGroupPerPage = true,
                        SpacingBeforeAllGroupsSummary = 10f,
                    });
                })
                .MainTableDataSource(dataSource =>
                {
                    dataSource.DataTable(dt);
                })
                .MainTableSummarySettings(summarySettings =>
                {
                    summarySettings.PreviousPageSummarySettings("نقل از صفحه قبل");
                })
                .MainTableColumns(columns =>
                {
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("سال");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Center);
                        column.IsVisible(true);
                        column.Order(0);
                        column.Width(2);
                        column.HeaderCell("سال تحصیلی");
                    });
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("نیمسال");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(1);
                        column.Width(1);
                        column.HeaderCell("نیمسال");
                       
                    });
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("پایه");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(2);
                        column.Width(1);
                        column.HeaderCell("پایه");
                    });
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("درس");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(3);
                        column.Width(1);
                        column.HeaderCell("درس");
                    });
                    for (int i = 6; i < countScore + 6; i++)
                    {
                            columns.AddColumn(column =>
                        {
                            column.PropertyName(dt.Columns[i].ToString());
                            column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                            column.IsVisible(true);
                            column.Order(i - 2);
                            column.Width(1);
                            column.HeaderCell(dtTitle.Rows[0][i - 5].ToString());
                        });
                     
                    }
                    
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("FinalScore1");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(countScore + 4);
                        column.Width(1);
                        column.HeaderCell("نمره نهایی");
                    });
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("t_term1");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(countScore+5);
                        column.Width(1);
                        column.HeaderCell("نمره تجدیدی");
                    });
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("t_term11");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(countScore + 6);
                        column.Width(1);
                        column.HeaderCell("نمره استادیاری");
                    });
                   
                   
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("tabestan1");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(countScore + 10);
                        column.Width(1);
                        column.HeaderCell("نمره تابستان");
                    });
                    
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("viewTermic");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(countScore + 11);
                        column.Width(1);
                        column.HeaderCell("ترم نمایشی");
                    });
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("Ghabol");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(countScore + 12);
                        column.Width(1);
                        column.HeaderCell("قبول");
                    });
                });
               

                return  pdfrpt.MainTableEvents(events =>
                   {
                       events.DataSourceIsEmpty(message: "داده ای برای نمایش وجو د ندارد");
                       events.MainTableAdded(args =>
                       {
                           var taxTable = new PdfPTable(1);  // Create a clone of the MainTable's structure
                           taxTable.RunDirection = 3;
                           //taxTable.SetWidths(new float[] { 3, 3, 3 });
                           taxTable.WidthPercentage = 100f;
                           taxTable.SpacingBefore = 10f;

                           taxTable.AddSimpleRow(
                               (data, cellProperties) =>
                               {
                                   data.Value = "مهر و امضای مدیر";
                                   cellProperties.ShowBorder = false;
                                   cellProperties.HorizontalAlignment = HorizontalAlignment.Left;
                                   cellProperties.PdfFont = args.PdfFont;
                               });
                           args.PdfDoc.Add(taxTable);
                       });
                   })
                .Export(export =>
                {
                    // export.ToExcel();
                })
                .Generate(data => data.AsPdfFile(fo.Name));
               
            }

مطالب
لیست اکران‌های نوروزی MIX09

MIX09 | Web Design and Development Conference






اشتراک‌ها
0.Visual Studio 2017 15.9 منتشر شد

Summary of Notable New Features in 15.9

Top Issues Fixed in 15.9

0.Visual Studio 2017 15.9 منتشر شد
مطالب
ساخت بسته‌های نیوگت مخصوص NET Core.
فایل‌های nuspec مخصوص سایر نگارش‌های دات نت، در NET Core. ندید گرفته شده و پردازش نمی‌شوند. در اینجا نیز تمام تنظیمات تولید بسته‌های نیوگت، در فایل project.json درج می‌شوند که در ادامه آن‌ها را بررسی خواهیم کرد.


فعالسازی تولید خودکار بسته‌های نیوگت در پروژه‌های NET Core.

پس از تهیه‌ی یک کتابخانه‌ی مبتنی بر NET Core.، تنها کاری که در جهت تولید خودکار بسته‌های نیوگت باید انجام شود، افزودن مدخل postcompile ذیل به فایل project.json است:
    "scripts": {
        "postcompile": [
            "dotnet pack --no-build --configuration %compile:Configuration%"
        ]
    }
پس از آن هربار که پروژه کامپایل شود، به صورت خودکار فایل nupkg نهایی در پوشه‌ی bin\Release تشکیل می‌شود.
در این‌حالت اگر فایل nupkg تولیدی را توسط برنامه‌های zip باز کنید، مشاهده خواهید کرد که فایل nuspec خودکاری نیز در آن درج شده‌است؛ اما ... مشخصات ثبت شده‌ی در آن ناقص هستند و شامل مواردی مانند نام پروژه، نام نویسنده، مجوز استفاده‌ی از پروژه، آدرس پروژه و امثال آن‌ها نیستند. در نگارش‌های دیگر دات نت، این مشخصات از فایل nuspec تهیه شده‌ی توسط ما جمع آوری و درج می‌شود. اما در اینجا خیر.


تکمیل فایل project.json برای درج مشخصات پروژه و تکمیل اطلاعات فایل nuspec

هرچند به ظاهر دیگر فایل nuspec دستی تهیه شده در اینجا پردازش نمی‌شود، اما تمام اطلاعات آن‌را در فایل project.json نیز می‌توان درج کرد:
{
    "version": "1.1.1.0",
    "authors": [ "Vahid Nasiri" ],
    "packOptions": {
        "owners": [ "Vahid Nasiri" ],
        "tags": [ "PdfReport", "Excel", "Export", "iTextSharp", "PDF", "Report", "Reporting", "Persian", ".NET Core" ],
        "licenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.0-standalone.html",
        "projectUrl": "https://github.com/VahidN/iTextSharp.LGPLv2.Core"
    },
    "description": " iTextSharp.LGPLv2.Core  is an unofficial port of the last LGPL version of the iTextSharp (V4.1.6) to .NET Core.",

    "scripts": {
        "postcompile": [
            "dotnet pack --no-build --configuration %compile:Configuration%"
        ]
    }
}
در اینجا یک نمونه از مشخصات فایل project.json ایی را مشاهده می‌کنید که در آن مواردی مانند نویسندگان، برچسب‌هایی که در سایت نیوگت لیست خواهند شد، آدرس مجوز پروژه، آدرس مخزن کد پروژه و توضیحات آن، تکمیل شده‌اند. قسمت postcompile، دقیقا همین اطلاعات را جهت تولید فایل خودکار nuspec نهایی، استفاده می‌کند.


تکمیل تنظیمات Build پروژه

بهتر است کتابخانه‌های خود را در حالت release و همچنین بهینه سازی شده، توزیع کنید. به همین منظور نیاز است مدخل ذیل را نیز به فایل project.json اضافه کرد:
    "configurations": {
        "Release": {
            "buildOptions": {
                "optimize": true,
                "platform": "anycpu"
            }
        }
    },


افزودن مستندات XML ایی کتابخانه

به احتمال زیاد XML-Docهای هر متد (کامنت‌های مخصوص دات نتی هر متد یا خاصیت عمومی) را نیز به کدهای خود افزوده‌اید. برای اینکه فایل XML نهایی آن به صورت خودکار تولید شده و همچنین در بسته‌ی نیوگت نهایی درج شود، نیاز است مدخل xmlDoc را به buildOptions اضافه کنید:
    "buildOptions": {
        "xmlDoc": true
    },
در این حالت هر عنصری با سطح دسترسی public، باید دارای کامنت باشد. اگر می‌خواهید مجبور به انجام اینکار نشوید و کامپایلر اخطار صادر نکند، می‌توانید از اخطار شماره‌ی 1591 صرفنظر کنید:
    "buildOptions": {
        "xmlDoc": true,
        "nowarn": [ "1591" ] // 1591: missing xml comment for publicly visible type or member
    },


برای مطالعه‌ی بیشتر
project.json reference
مطالب
نحوه‌ی صحیح فراخوانی SQL Aggregate Functions حین استفاده از LINQ

SQL Aggregate Functions که مد نظر شما هستند مانند Min ، Max ، Sum و امثال آن. بحث LINQ هم زمانیکه از الگوی Repository استفاده شود مستقل از نوع ORM مورد نظر خواهد شد؛ بنابراین در اینجا مقصود از LINQ می‌تواند LINQ to SQL ، LINQ to Entities ، LINQ to NHibernate و کلا هر نوع ORM دیگری با پشتیبانی از LINQ باشد.
صورت مساله هم این است: آیا نوشتن عبارت LINQ ایی به شکل زیر صحیح است؟
decimal amount = respository.Transactions
.Where(t=>t.TransactionDate>new DateTime(2010,10,13))
.Sum(t=>t.Amount);
پاسخ: خیر!
توضیحات:
عبارت LINQ فوق در نهایت به شکل زیر ترجمه خواهد شد:
-- Region Parameters
-- @p0: DateTime [2010/10/13 12:00:00 ق.ظ]
-- EndRegion
SELECT SUM([t0].[Amount]) AS [value]
FROM [Transactions] AS [t0]
WHERE [t0].[TransactionDate] > @p0
و اتفاقا در این سیستم پس از تاریخ 2010/10/13 هیچ تراکنشی ثبت نشده است؛ بنابراین خروجی این کوئری null خواهد بود و نه صفر. همینجا است که یکی از استثناهای زیر صادر شده و ادامه‌ی برنامه با مشکل مواجه خواهد شد:
- System.InvalidOperationException: The cast to value type 'decimal' failed because the materialized value is null.
- InvalidOperationException: The null value cannot be assigned to a member with type decimal which is a non-nullable value type.

مشکل هم از اینجا ناشی می‌شود که متغییری از نوع deciaml یا int و امثال آن، مقدار دریافتی نال را نمی‌پذیرند. برای رفع این مشکل باید عبارت LINQ فوق به صورت زیر بازنویسی شود (و اهمیتی هم ندارد که Sum است یا Max یا Avg و غیره؛ در مورد بکارگیری تمام SQL Aggregate Functions در یک عبارت LINQ ، این مورد باید لحاظ گردد):
decimal amount = respository.Transactions
.Where(t=>t.TransactionDate>new DateTime(2010,10,13))
.Sum(t=>(decimal?)t.Amount)??0;

دقیقا به همین علت است که در دات نت، nullable types تعریف شده‌اند. امکان ذخیره سازی null‌ در یک متغیر برای مثال از نوع decimal وجود ندارد اما نوع decimal? (و یا Nullable<decimal> به بیانی دیگر) این قابلیت را دارد.
شاید بگوئید که در اینجا با تغییر تعریف متغیر به decimal? amount مشکل حل می‌شود، اما خیر. تعریف extension method مربوط به sum به صورت زیر است:

public static TResult Sum<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, TResult>> selector)

در این تعریف به TResult دقت نمائید؛ هم بیانگر نوع خروجی نهایی متد و هم مشخص سازنده‌ی نوع پارامتری است که خروجی Lambda Expression را تشکیل می‌دهد. به این معنا که سی شارپ، TResult را از lambda expression دریافت کرده و خروجی Sum را بر همان مبنا و نوع تشکیل می‌دهد. بنابراین برای دریافت خروجی nullable باید TResult ایی nullable را همانند مثال فوق ایجاد کنیم.

خلاصه بحث:
اگر در کدهای LINQ خود که با بانک اطلاعاتی سر و کار دارند از معادل‌های SQL Aggregate Functions استفاده کرده‌اید، آن‌ها را یافته و نکته‌ی nullable TResult فوق را به آن‌ها اعمال کنید؛ در غیر اینصورت منتظر باشید تا روزی برنامه شما به سادگی کرش کند.


مطالب
اتصال Node.js به SQL Server با استفاده از Edge.js
اگر خواسته باشید که با استفاده از Node.js به SQL Server متصل شوید، احتمالا متوجه شده‌اید ماژولی که مایکروسافت منتشر کرده است، ناقص بوده و به صورت پیش نمایش است که بسیاری از ویژگی‌ها و مسائل مهم، در آن در نظر گرفته نشده است.

یکی دیگر از ماژول‌هایی که امکان اتصال Node.js را به SQL Server ممکن می‌کند، Edge.js است. Edge.js یک ماژول Node.js است که امکان اجرای کدهای دات نت را در همان پروسه توسط Node.js فراهم می‌کند. این مسئله، توسعه دهندگان Node.js را قادر می‌سازد تا از فناوری‌هایی که به صورت سنتی استفاده‌ی از آنها سخت یا غیر ممکن بوده است را به راحتی استفاده کنند. برای نمونه:
  • SQL Server
  • Active Directory
  • Nuget packages
  • استفاده از سخت افزار کامپیوتر (مانند وب کم، میکروفن و چاپگر)


نصب Node.js

اگر Node.js را بر روی سیستم خود نصب ندارید، می‌توانید از اینجا آن را دانلود کنید. بعد از نصب برای اطمینان از کارکرد آن، command prompt را باز کرده و دستور زیر را تایپ کنید:

node -v
شما باید نسخه‌ی نصب شده‌ی Node.js را مشاهده کنید.

ایجاد پوشه پروژه

سپس پوشه‌ای را برای پروژه Node.js خود ایجاد کنید. مثلا با استفاده از command prompt و دستور زیر:

md \projects\node-edge-test1
cd \projects\node-edge-test1

نصب Edge.js

Node با استفاده از package manager خود دانلود و نصب ماژول‌ها را خیلی آسان کرده است. برای نصب، در command prompt عبارت زیر را تایپ کنید:

npm install edge
npm install edge-sql
فرمان اول باعث نصب Edge.js و دومین فرمان سبب نصب پشتیبانی از SQL Server می‌شود.

Hello World

ایجاد یک فایل متنی با نام server.js و نوشتن کد زیر در آن:
var edge = require('edge');

// The text in edge.func() is C# code
var helloWorld = edge.func('async (input) => { return input.ToString(); }');

helloWorld('Hello World!', function (error, result) {
    if (error) throw error;
    console.log(result);
});
حالا برای اجرای این Node.js application از طریق command prompt کافی است به صورت زیر عمل کنید:
node server.js
همانطور که مشاهده می‌کنید "!Hello World" در خروجی چاپ شد.

ایجاد پایگاه داده تست

در مثال‌های بعدی، نیاز به یک پایگاه داده داریم تا query‌ها را اجرا کنیم. در صورتی که SQL Server بر روی سیستم شما نصب نیست، می‌توانید نسخه‌ی رایگان آن را از اینجا دانلود و نصب کنید. همچنین SQL Management Studio Express را نیز نصب کنید.

  1. در SQL Management Studio، یک پایگاه داده را با نام node-test با تنظیمات پیش فرض ایجاد کنید.
  2. بر روی پایگاه داده node-test راست کلیک کرده و New Query را انتخاب کنید.
  3. اسکریپت زیر را copy کرده و در آنجا paste کنید، سپس بر روی Execute کلیک کنید.
IF EXISTS(SELECT 1 FROM sys.tables WHERE object_id = OBJECT_ID('SampleUsers')) BEGIN; DROP TABLE SampleUsers; END; GO

CREATE TABLE SampleUsers ( Id INTEGER NOT NULL IDENTITY(1, 1), FirstName VARCHAR(255) NOT NULL, LastName VARCHAR(255) NOT NULL, Email VARCHAR(255) NOT NULL, CreateDate DATETIME NOT NULL DEFAULT(getdate()), PRIMARY KEY (Id) ); GO

INSERT INTO SampleUsers(FirstName,LastName,Email,CreateDate) VALUES('Orla','Sweeney','nunc@convallisincursus.ca','Apr 13, 2014');
INSERT INTO SampleUsers(FirstName,LastName,Email,CreateDate) VALUES('Zia','Pickett','porttitor.tellus.non@Duis.com','Aug 31, 2014');
INSERT INTO SampleUsers(FirstName,LastName,Email,CreateDate) VALUES('Justina','Ayala','neque.tellus.imperdiet@temporestac.com','Jul 28, 2014');
INSERT INTO SampleUsers(FirstName,LastName,Email,CreateDate) VALUES('Levi','Parrish','adipiscing.elit@velarcueu.com','Jun 21, 2014');
INSERT INTO SampleUsers(FirstName,LastName,Email,CreateDate) VALUES('Pearl','Warren','In@dignissimpharetra.org','Mar 3, 2014');
نتیجه‌ی اجرای کد بالا، ایجاد جدولی با نام SampleUsers و درج 5 رکورد در آن می‌شود.

تنظیمات ConnectionString

قبل از استفاده از Edge.js با SQL Server، باید متغیر محیطی (environment variable) با نام EDGE_SQL_CONNECTION_STRING را تعریف کنید.

set EDGE_SQL_CONNECTION_STRING=Data Source=localhost;Initial Catalog=node-test;Integrated Security=True
این متغیر تنها برای command prompt جاری تعریف شده است و با بستن آن از دست می‌رود. در صورتیکه از Node.js Tools for Visual Studio استفاده می‌کنید، نیاز به ایجاد یک متغیر محیطی دائمی و راه اندازی مجدد VS دارید. همچنین در صورتیکه بخواهید متغیر محیطی دائمی ایجاد کنید، فرمان زیر را اجرا کنید:
SETX EDGE_SQL_CONNECTION_STRING "Data Source=localhost;Initial Catalog=node-test;Integrated Security=True"


روش اول: اجرای مستقیم SQL Server Query در Edge.js

فایلی با نام server-sql-query.js را ایجاد کرده و کد زیر را در آن وارد کنید:

var http = require('http');
var edge = require('edge');
var port = process.env.PORT || 8080;

var getTopUsers = edge.func('sql', function () {/*
    SELECT TOP 3 * FROM SampleUsers ORDER BY CreateDate DESC
*/});

function logError(err, res) {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.write("Error: " + err);
    res.end("");
}    

http.createServer(function (req, res) {
    res.writeHead(200, { 'Content-Type': 'text/html' });

    getTopUsers(null, function (error, result) {
        if (error) { logError(error, res); return; }
        if (result) {
            res.write("<ul>");
            result.forEach(function(user) {
                res.write("<li>" + user.FirstName + " " + user.LastName + ": " + user.Email + "</li>");
            });
            res.end("</ul>");
        }
        else {
        }
    });
}).listen(port);
console.log("Node server listening on port " + port);
سپس با استفاده از command prompt، فرمان زیر را اجرا کنید:
node server-sql-query.js
حال مرورگر خود را باز و سپس آدرس http://localhost:8080 را باز کنید. در صورتی که همه چیز به درستی انجام گرفته باشد لیستی از 3 کاربر را خواهید دید.

روش دوم: اجرای کد دات نت برای SQL Server Query

Edge.js تنها از دستورات Update، Insert، Select و Delete پشتیبانی می‌کند. در حال حاضر از store procedures و مجموعه‌ای از کد SQL پشتیبانی نمی‌کند. بنابراین، اگر چیزی بیشتر از عملیات CRUD می‌خواهید انجام دهید، باید از دات نت برای این کار استفاده کنید.

یادتان باشد، همیشه async

مدل اجرایی Node.js به صورت یک حلقه‌ی رویداد تک نخی است. بنابراین این بسیار مهم است که کد دات نت شما به صورت async باشد. در غیر اینصورت یک فراخوانی به دات نت سبب مسدود شدن و ایجاد خرابی در Node.js می‌شود.

ایجاد یک Class Library

اولین قدم، ایجاد یک پروژه Class Library در Visual Studio که خروجی آن یک فایل DLL است و استفاده از آن در Edge.js است. پروژه Class Library با عنوان EdgeSampleLibrary ایجاد کرده و فایل کلاسی با نام Sample1 را به آن اضافه کنید و سپس کد زیر را در آن وارد کنید:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;

namespace EdgeSampleLibrary
{
     public class Sample1
    {
        public async Task<object> Invoke(object input)
        {
            // Edge marshalls data to .NET using an IDictionary<string, object>
            var payload = (IDictionary<string, object>) input;
            var pageNumber = (int) payload["pageNumber"];
            var pageSize = (int) payload["pageSize"];
            return await QueryUsers(pageNumber, pageSize);
        }

        public async Task<List<SampleUser>> QueryUsers(int pageNumber, int pageSize)
        {
            // Use the same connection string env variable
            var connectionString = Environment.GetEnvironmentVariable("EDGE_SQL_CONNECTION_STRING");
            if (connectionString == null)
                throw new ArgumentException("You must set the EDGE_SQL_CONNECTION_STRING environment variable.");

            // Paging the result set using a common table expression (CTE).
            // You may rather do this in a stored procedure or use an 
            // ORM that supports async.
            var sql = @"
DECLARE @RowStart int, @RowEnd int;
SET @RowStart = (@PageNumber - 1) * @PageSize + 1;
SET @RowEnd = @PageNumber * @PageSize;

WITH Paging AS
(
    SELECT  ROW_NUMBER() OVER (ORDER BY CreateDate DESC) AS RowNum,
            Id, FirstName, LastName, Email, CreateDate
    FROM    SampleUsers
)
SELECT  Id, FirstName, LastName, Email, CreateDate
FROM    Paging
WHERE   RowNum BETWEEN @RowStart AND @RowEnd
ORDER BY RowNum;
";
            var users = new List<SampleUser>();

            using (var cnx = new SqlConnection(connectionString))
            {
                using (var cmd = new SqlCommand(sql, cnx))
                {
                    await cnx.OpenAsync();

                    cmd.Parameters.Add(new SqlParameter("@PageNumber", SqlDbType.Int) { Value = pageNumber });
                    cmd.Parameters.Add(new SqlParameter("@PageSize", SqlDbType.Int) { Value = pageSize });

                    using (var reader = await cmd.ExecuteReaderAsync(CommandBehavior.CloseConnection))
                    {
                        while (await reader.ReadAsync())
                        {
                            var user = new SampleUser
                            {
                                Id = reader.GetInt32(0), 
                                FirstName = reader.GetString(1), 
                                LastName = reader.GetString(2), 
                                Email = reader.GetString(3), 
                                CreateDate = reader.GetDateTime(4)
                            };
                           users.Add(user);
                        }
                    }
                }
            }
            return users;
        } 
    }

    public class SampleUser
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public DateTime CreateDate { get; set; }
    }
}
سپس ذخیره و کامپایل کنید. فایل DLL خروجی که در مسیر
[project]/bin/Debug/EdgeSampleLibrary.dll
قرار دارد را در پوشه‌ی پروژه Node کپی کنید. فایل جدیدی را با نام server-dotnet-query.js در پروژه Node ایجاد کنید و کد زیر را در آن وارد کنید:
var http = require('http');
var edge = require('edge');
var port = process.env.PORT || 8080;

// Set up the assembly to call from Node.js 
var querySample = edge.func({ assemblyFile: 'EdgeSampleLibrary.dll', typeName: 'EdgeSampleLibrary.Sample1', methodName: 'Invoke' });

function logError(err, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write("Got error: " + err); res.end(""); }

http.createServer(function (req, res) { res.writeHead(200, { 'Content-Type': 'text/html' });

    // This is the data we will pass to .NET
    var data = { pageNumber: 1, pageSize: 3 };

    // Invoke the .NET function
    querySample(data, function (error, result) {
        if (error) { logError(error, res); return; }
        if (result) {
            res.write("<ul>");
            result.forEach(function(user) {
                res.write("<li>" + user.FirstName + " " + user.LastName + ": " + user.Email + "</li>");
            });
            res.end("</ul>");
        }
        else {
            res.end("No results");
        }
    });

}).listen(port);

console.log("Node server listening on port " + port);
سپس از طریق command prompt آن را اجرا کنید:
node server-dotnet-query.js
حال مرورگر خود را باز کرده و به آدرس http://localhost:8080 بروید. در صورتیکه همه چیز به درستی انجام گرفته باشد، لیستی از 3 کاربر را خواهید دید. مقادیر pageNumber و pageSize را در فایل جاوااسکریپت تغییر دهید و تاثیر آن را بر روی خروجی مشاهده کنید.
 
نکته: برای ایجاد pageNumber و pageSize داینامیک با استفاده از ارسال مقادیر توسط QueryString، می‌توانید از ماژول connect استفاده کنید.