نظرات اشتراک‌ها
پروژه‌ی MoreLINQ
دو برنامه نویس از بین  contributor  ها همان ابتدا من رو خیره کردند ، یکی John Skeet  کسی که در حال حاضر بالاترین امتیاز رو در starckoverflow.com دارد و دیگری Atif Aziz مبدع ELMAH .
مطالب
خواندن سریع اطلاعات فایل اکسل و ذخیره در بانک SQL
یکی از زمانبرترین عملیاتها در نرم افزار‌های اتوماسیون، خواندن اطلاعات از فایل‌های اکسل با حجم بالا است. در صورتی که این کار را می‌توان با استفاده از کلاس SqlBulkCopy  به سرعت انجام داد. در ادامه نحوه استفاده از این کلاس، همراه نمونه کدها آورده شده است.
توضیحات به صورت Comment است.
            try
            {
//انتخاب فایل اکسل
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Title = "انتخاب فایل اکسل حاوی اطلاعات";
                ofd.Filter = "فایل اکسل 2003 (*.xls)|*.xls|فایل اکسل 2007 به بعد(*.xlsx)|*.xlsx";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    string excelConnectionString = "";
                    string SourceFilePath = ofd.FileName;
//ایجاد کانکشن استرینگ برا خواندن کل اطلاعات از فایل اکسل و ریختن آنها در یک دیتاتیبل به نام dt
                    if (System.IO.Path.GetExtension(ofd.FileName) == ".xlsx")
//تشخیص نوع فایل اکسل برای ایجاد کانکشن استرینگ برای نسخه‌های مختلف اکسل
                        excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + SourceFilePath + ";Extended Properties=Excel 12.0";
                    else if (System.IO.Path.GetExtension(ofd.FileName) == ".xls")
                        excelConnectionString = "Provider=Microsoft.Jet.Oledb.4.0;Data Source=" + SourceFilePath + ";Extended Properties=Excel 8.0";

                    DataTable dt = new DataTable("tblinfos");


                    using (System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection(excelConnectionString))
                    {
                       
                        connection.Open();

                        System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter("SELECT * FROM [List$]", connection);//List نام شیت در فایل اکسل است

                        da.Fill(dt);
                        connection.Close();

                    }

                    using (System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection(excelConnectionString))
                    {
                        this.Cursor = Cursors.WaitCursor;

                        connection.Open();
//ایجاد ارتباط با بانک اس کیو ال
                        string sqlConnectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\BankDPR.mdf;Max Pool Size=6000; Connection Timeout=50;Integrated Security=True;User Instance=True";
                        

                        Dataaccess db = new Dataaccess();
                        DataTable dtr = db.select("Select Top(1) * From tblinfos");//بدست آورن نام ستون‌های جدول مورد نظر برای تطبیق با ستونهای فایل اکسل
                        //*******************   Fast Copy
                        using (System.Data.SqlClient.SqlBulkCopy bulkCopy = new System.Data.SqlClient.SqlBulkCopy(sqlConnectionString, System.Data.SqlClient.SqlBulkCopyOptions.KeepIdentity))//تعریف یک شی از کلاس SqlBulkCopy 
                        {
                            for (int i = 1; i < dtr.Columns.Count; i++)
                            {
                                bulkCopy.ColumnMappings.Add(dt.Columns[i - 1].Caption, dtr.Columns[i].Caption);//با استفاده از خاصیت ColumnMappings نام ستونهای فایل اکسل با نام ستونهای جدول مورد نظر بانک sql تطبیق داده می‌شود
                            }

                            bulkCopy.DestinationTableName = "tblinfos";//مشخص نمودن نام جدول که قرار است اطلاعات درون ان کپی گردد
                            bulkCopy.WriteToServer(dt);//انجام عملیات کپی اطلاعات از دیتاتیبل با نام dt به بانک

                        }

                        this.Cursor = Cursors.Arrow;
                        MessageBox.Show("اطلاعات از فایل شما خوانده شد");

                    }
                }
            }
            catch (Exception ex)
            {
                this.Cursor = Cursors.Arrow;

                MessageBox.Show(ex.Message, "error");
            }

مطالب
بررسی صحت پشتیبان‌های تهیه شده در SQL Server

اولین و اساسی‌ترین قدم در نگهداری یک سیستم مبتنی بر داده، تهیه پشتیبان‌های منظم و همچنین قابل اطمینان می‌باشد.
دستور T-SQL زیر بدون ری‌استور کردن یک فایل بک آپ اس کیوال سرور، سعی در تعیین اعتبار آن می‌کند:
RESTORE VERIFYONLY
FROM DISK = 'C:\SQL_Backup\Test1'
WITH FILE = 1,
LOADHISTORY
این دستور وضعیت کامل بودن پشتیبان و همچنین قابل خواندن بودن اطلاعات آن‌را برسی می‌کند و در صورت سالم بودن بک آپ، پیغام زیر را نمایش خواهد داد:

The backup set on file 1 is valid.
عموما عملیات تهیه پشتیبان در یک مکان مشخص در سرور صورت می‌گیرد (خصوصا اگر یک job مختص به آن تعریف شده باشد که این‌کار را به صورت خودکار انجام دهد). بنابراین می‌توان عملیات اعتبار سنجی فوق را مکانیزه کرد. اسکریپت زیر مسیر آخرین بک آپ‌های گرفته شده در سرور را بر می‌گرداند:
SELECT DISTINCT physical_device_name
FROM msdb.dbo.backupmediafamily
ORDER BY
physical_device_name
اکنون می‌توان مسیر‌های فوق را در یک cursor جهت بررسی صحت تک تک موارد استفاده نمود:

DECLARE @path NVARCHAR(1000),
@msg NVARCHAR(MAX),
@NewLine CHAR(2),
@sql NVARCHAR(2000)

SET @NewLine = CHAR(13) + CHAR(10)
SET @msg = ''

DECLARE DATABASES_CURSOR CURSOR
FOR
SELECT DISTINCT physical_device_name
FROM msdb.dbo.backupmediafamily
ORDER BY
physical_device_name

OPEN DATABASES_CURSOR

FETCH NEXT FROM DATABASES_CURSOR INTO @path

WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Verifying: ' + @path
SET @sql = 'RESTORE VERIFYONLY FROM DISK = ''' + @path
+ ''' WITH FILE = 1, LOADHISTORY'

EXEC sp_executesql @sql
IF @@ERROR <> 0
BEGIN
SET @msg = @msg + 'Failed to verify: ' + @path + @NewLine
END

FETCH NEXT FROM DATABASES_CURSOR INTO @path
END

CLOSE DATABASES_CURSOR
DEALLOCATE DATABASES_CURSOR

IF @msg <> ''
BEGIN
PRINT @msg
-- send email
EXECUTE msdb.dbo.sp_send_dbmail
@recipients = 'nasiri@site.net', -- Change This
@copy_recipients = 'Administrator@site.net', -- Change This
@Subject = 'backup verification info.',
@Body = @msg
,@importance = 'High'

END

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

مطالب
آشنایی با قابلیت FileStream اس کیوال سرور 2008 - قسمت دوم

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

فعال سازی قابلیت FileStream
همانند اکثر قابلیت‌های اس کیوال سرور، فعال سازی FileStream نیز حداقل به دو صورت استفاده از GUI و قابلیت‌های management studio میسر است و یا استفاده از دستورات T-SQL (و البته کتابخانه‌ی SMO یا همان محصور کننده‌ی توانایی‌های management studio نیز قابل استفاده است).

روش اول) استفاده از management studio
قابلیت FileStream به صورت پیش فرض غیرفعال است. برای فعال سازی آن به مسیر زیر مراجعه نمائید:

Start > All Programs > Microsoft SqlServer 2008 > Configuration Tools > SQL Server Configuration Manager

سپس در قسمت SQL Server services ، وهله مربوط به SQL Server را یافته، کلیک راست و به برگه خواص آن مراجعه کرده (شکل زیر) و قابلیت FileStream را فعال کنید:



گزینه‌های مختلف آن به شرح زیر هستند:
• Enable FileStream for transact-sql access : امکان استفاده از دستورات T-SQL را جهت دسترسی به فایل‌ها فعال می‌سازد (یا برعکس)
• Enable FileStream for File I/O streaming access : امکان دسترسی به فایل‌ها با استفاده از Win32 streaming access
• All remote clients to have streaming access to file stream data : اجازه‌ی دسترسی به کلاینت‌های راه دور جهت استفاده از قابلیت FileStream

مرحله بعد، فعال سازی سطح دسترسی به سرور است. به management studio مراجعه نمائید. سپس بر روی وهله سرور مورد نظر کلیک راست نموده و به خواص آن مراجعه کنید (شکل زیر). سپس در قسمت advanced سطح دسترسی را بر روی Full قرار دهید.



پس از این تنظیم به شما پیغام داده خواهد شد که باید دیتابیس سرور را یکبار راه اندازی مجدد نمائید تا تنظیمات مورد نظر، اعمال شوند.

در ادامه باید دیتابیسی را که نیاز است نوع داده FileStream را بپذیرد، تنظیم نمود.
بر روی دیتابیس مورد نظر کلیک راست کرده و در برگه خواص آن به گزینه‌ی Filegroups مراجعه کنید. سپس در اینجا یک گروه جدید را اضافه کرده ، نامی دلخواه را وارد نموده و سپس تیک مربوط به default بودن آن‌را نیز قرار دهید (شکل زیر):



سپس در همین برگه‌ی خواص دیتابیس که باز است، به گزینه‌ی Files مراجعه کنید. در اینجا سه کار را باید انجام دهید. ابتدا بر روی دکمه Add کلیک کرده و در قسمت logical name ردیف اضافه شده، نامی دلخواه را وارد کنید. سپس file type آن را بر روی FileStream قرار دهید. در ادامه به قسمت path در همین ردیف مراجعه نموده و مسیر ذخیره سازی را مشخص کنید. در پایان بر روی دکمه‌ی OK کلیک نمائید تا کار تنظیم دیتابیس به پایان رسد (شکل زیر):



روش دوم) استفاده از دستورات T-SQL
منهای قسمت تنظیمات SQL Server Configuration Manager که باید از طریق روش عنوان شده صورت گیرد، سایر موارد فوق را با استفاده از دستورات T-SQL نیز می‌توان انجام داد:

الف) تنظیم سطح دسترسی بر روی سرور

EXEC sp_configure filestream_access_level, 2 -- 0 : Disable , 1 : Transact Sql Access , 2 : Win IO Access
GO
RECONFIGURE
GO
ب) تنظیمات دیتابیس

اگر نیاز باشد دیتابیس جدیدی ایجاد شود: (ایجاد گروه فایل مربوطه و سپس تنظیمات مسیر آن)

CREATE DATABASE Test_Db
ON
PRIMARY ( NAME = TestDb1,
FILENAME = 'C:\DATA\Test_Db.mdf'),
FILEGROUP FileStreamGroup1 CONTAINS FILESTREAM( NAME = Testfsg1,
FILENAME = 'C:\DATA\Learning_DbStream')
LOG ON ( NAME = TestDbLog1,
FILENAME = 'C:\DATA\Test_Db.ldf')
GO

و یا ایجاد تغییرات بر روی دیتابیسی موجود: (ایجاد گروه فایل مخصوص و سپس افزودن فایل مربوطه و تنظیمات آن)

--add filegroup
alter database TestDb
Add FileGroup FileStreamFileGroup1 contains FileStream
go

--Add FileGroup To DB
alter database TestDB
add file
(
name = 'UserDocuments' ,
filename = 'C:\FileStream\UserDocuments'
) to filegroup FileStreamFileGroup1


تعریف جدولی آزمایشی به همراه فیلدی از نوع FileStream :
تا اینجا سرور و همچنین دیتابیس جهت پذیرش این نوع داده آماده شدند. اکنون نوبت به استفاده از آن است:

CREATE TABLE [tblFiles]
(
FileId UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL UNIQUE DEFAULT(NEWID()),
Title NVARCHAR(255) NOT NULL,
SystemFile VARBINARY(MAX) FILESTREAM NULL
)
ON [PRIMARY] FILESTREAM_ON [fsg1]

توسط دستور T-SQL فوق جدولی که از نوع داده FileStream استفاده می‌کند، ایجاد خواهد شد. این جدول همانطور که مشخص است حتما باید دارای یک فیلد منحصربفرد باشد (ر.ک. مقاله قبل) و همچنین برچسب فایل استریم به فیلدی از نوع VARBINARY(MAX) نیز الصاق شده است. به علاوه گروه فایل آن نیز باید به صورت صریح مشخص گردد؛ که در مثال ما مطابق تصاویر به fsg1 تنظیم شده بود.

ادامه دارد ...

نظرات مطالب
شروع کار با Apache Cordova در ویژوال استودیو #2

سلام مرسی بابت مطلبتون لطفاً راهنماییم کنین
مسیری هم که توی path دادم به این شکل هست
C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Microsoft SQL Server\120\DTS\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\ManagementStudio\;C:\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn\;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files (x86)\Skype\Phone\;C:\Program Files (x86)\CodeSmith\v5.2\;C:\Program Files (x86)\nodejs\;C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\;%JAVA_HOME%\bin;%ADT_HOME%\tools;%ADT_HOME%\platform-tools;%ANT_HOME%\bin;%GIT_HOME%\cmd;C:\Program Files (x86)\nodejs\;%JAVA_HOME%\bin;%ANT_HOME%\bin;%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools;E:\Android Softwares\android-sdk Complete\android-sdk;

مسیر sdk هم اینجا هست
E:\Android Softwares\android-sdk Complete\android-sdk

 

در ضمن  path قبلی هم این بود

C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Microsoft SQL Server\120\DTS\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\ManagementStudio\;C:\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn\;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files (x86)\Skype\Phone\;C:\Program Files (x86)\CodeSmith\v5.2\;C:\Program Files (x86)\nodejs\;C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\;%JAVA_HOME%\bin;%ADT_HOME%\tools;%ADT_HOME%\platform-tools;%ANT_HOME%\bin;%GIT_HOME%\cmd


اما ارور زیر همچنان بر قرار است

 
مطالب
PowerShell 7x - قسمت اول - معرفی و نصب
PowerShell یک ابزار task automation است که همزمان یک command-line shell، زبان اسکریپتی و یک فریم‌ورک configuration management نیز میباشد. برخلاف دیگر shellها که مبتنی بر رشته هستند، ورودی و خروجی آن اشیاء دات‌نتی است و از آنجائیکه مبتنی بر CLR میباشد، امکان نوشتن توابع، کلاس‌ها و ماژول‌ها را به ما میدهد. همچنین به صورت توکار امکان کار با فرمت‌هایی از قبیل CSV, XML, JSON را در اختیارمان قرار میدهد. بخاطر extensible بودن، تعداد زیادی ماژول و افزونه برای نصب وجود دارند که کار با انواع تکنولوژی‌ها را میسر میسازند: 
  • Azure
  • Windows
  • Exchange
  • SQL
  • AWS
  • VMWare
  • Google Cloud
PowerShell در ابتدا در سال 2006 برای ویندوز XP به همراه 130 کامند ارائه شد. نسخه‌های بعدی آن نیز به ترتیب 2.0, 3.0, 4.0, 5.0 و در نهایت 5.1 به همراه تعداد بیشتری از Commandها ارائه شدند. تا اینجا فقط بر روی ویندوز استفاده بود، چون براساس Full .NET Framework توسعه داده شده بود، تا در نهایت در سال 2018 نسخه cross-platform آن یعنی نسخه 6.0 ارائه شد که مبتنی بر .NET Core 2 بود. در نسخه 6.2 تعداد Commandها به نصف تعداد نسخه 5.0 هم نمیرسید. در نهایت نسخه 7.0 ارائه شد که هم backward compatible بود و هم اینکه به صورت cross-platform نیز ارائه شد؛ لازم به ذکر است، این نسخه از PowerShell براساس .NET Core 3 توسعه یافت. PowerShell به صورت پیش‌فرض بر روی ویندوز ۷ (همچنین ویندوز ۲۰۰۸) به بعد، قابل نصب است. لازم به ذکر است که اسم پراسس PowerShell از نسخه ۷ به بعد از powershell.exe به pwsh.exe تغییر نام یافته است. بنابراین به صورت side-by-side در کنار PowerShell 5.1 قابل نصب است.


ISE یا همان Integrated Scripting Environment در واقع همان IDE برای نوشتن اسکریپت‌های چندخطی PowerShell است. از نسخه ۷ به بعد، PowerShell دیگر با ISE ارائه نمیشود و فقط برای ویندوز و در support mode است: 


برای نوشتن اسکریپت‌های PowerShell بهتر است extension رسمی آن را نصب کنید (+). با نصب این extension، محیط VSCode ظاهری شبیه به ISE پیدا خواهد کرد (البته به صورت پیش‌فرض فعال نیست و باید بعد از نصب theme را تغییر دهید). همچنین از Language Server مربوط به PowerShell نیز استفاده میکند که نوشتن و دیباگ کردن اسکریپت‌های PowerShell را به مراتب ساده‌تر خواهد کرد:
 

همچنین قابلیت IntelliSense  را نیز ارائه میدهد:

یکسری قابلیت‌های دیگر هم به همراه این extension به VSCode اضافه میشوند؛ به عنوان مثال PowerShell Script Analyzer نیز نصب خواهد شد که برای بررسی کیفیت کدها بسیار مفید است.


در اینجا میتوانید لیست کامل این ruleها را مشاهده کنید. از دیگر قابلیت‌های این extension میتوان به موارد زیر اشاره کرد:
  • Syntax highlighting
  • Code snippets
  • IntelliSense for cmdlets and more
  • Rule-based analysis provided by PowerShell Script Analyzer
  • Go to Definition of cmdlets and variables
  • Find References of cmdlets and variables
  • Document and workspace symbol discovery
  • Run selected selection of PowerShell code using F8
  • Launch online help for the symbol under the cursor using Ctrl+F1
  • Local script debugging
  • Extension Terminal support
  • PowerShell ISE color theme 

نصب PowerShell بر روی macOS 
نصب PowerShell به چند طریق قابل انجام است که در اینجا میتوانید مشاهده کنید؛ به عنوان مثال برای نصب PowerShell روی macOS تنها کافی است دستور زیر را وارد کنید: 
brew install --cask powershell
سپس دستور pwsh قابل استفاده خواهد بود: 
❯ pwsh
PowerShell 7.2.6
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

PS />

در قسمت‌های بعدی، مقدمات کار با PowerShell را توضیح خواهیم داد.
نظرات مطالب
نحوه تنظیم زمانبندی (Scheduling) برای Crawler در شیرپوینت
در وهله اول باید عرض کنم که این مقادیر صرفا جهت یه مثال و آموزش بیان شده اند و دلیل بر پیاده سازی مانند آنها وجود ندارد . ضمنا در تنظیمات ، نوع Indexing به صورت   incremental    است که در نتیجه به طور کامل جستجو انجام نمی‌شود . اما در مورد اینکه اصلا چرا باید ایندکس انجام شود باید عرض کنم که ساختار ایندکسر در شیرپوینت ، که بر مبنای Full-Text Index در SQL Server بنا شده است تمام محتویات سایت هایی که برای ایندکسر تعریف شده است (با توجه به سطح دسترسی تعریف شده) می‌خواند و به یک Stream از کاراکتر‌های unicode تبدیل میکند ، (به کمک IFilter مربوطه) سپس برنامه ای به نام word breaker واژه‌های رایج مانند And و OR و ... (noise words) را حذف کرده و اطلاعات آن واژه‌ها به همراه آدرسی که واژه‌ها وجود دارند بعلاوه سطح دسترسی آنها و تنظیمات امنیتی و ... را به کمک برنامه ای به نام Gatherer Program  در پایگاه داده sql نگه داری میکند (اگر واژه وجود داست فقط اطلاعات منبع ذخیره می‌شود) این پروسه به استخراج اطلاعات در سامانه جستجو کمک می‌کند . امــا در مورد  full-fledge   اطلاعات  کافی ندارم که بتونم راهنماییتون کنم . در صورتی که اطلاعاتی بدست آوردم ، حتما در اختیارتون قرار می‌دهم. موفق باشید
اشتراک‌ها
DataMasker پروژه‌ای برای درهم سازی خروجی اطلاعات Sql Server
A free data masking and/or anonymizer library for Sql Server written in .NET If you've ever needed to pull down databases from a live environment to stage or even dev you'll need to think about masking any personal information. There are options out there paid and free, however the free ones I've found do not provide genuine data and the paid options are too pricey when it's only a few tables.
DataMasker پروژه‌ای برای درهم سازی خروجی اطلاعات Sql Server
مطالب
RavenDB؛ تجربه متفاوت از پایگاه داده
" به شما خواننده گرامی پیشنهاد می‌کنم مطلب قبلی را مطالعه کنید تا پیش زمینه مناسبی در باره این مطلب کسب کنید. "

ماهیت این پایگاه داده وب سرویسی مبتنی بر REST است و فرمت اطلاعاتی که از سرور دریافت می‌شود، JSON است.

گام اول: باید آخرین نسخه RavenDB  را دریافت کنید. همان طور که مشاهده می‌کنید، ویرایش‌های مختلف کتابخانه هایی که برای نسخه Client و همچنین Server طراحی شده است، دراین فایل قرار گرفته است.

برای راه اندازی Server باید فایل Start را اجرا کنید، چند ثانیه بعد محیط مدیریتی آن را در مرورگر خود مشاهده می‌کنید. در بالای صفحه روی لینک Databases کلیک کنید و در صفحه باز شده گزینه New Database را انتخاب کنید. با دادن یک نام دلخواه حالا شما یک پایگاه داده ایجاد کرده اید. تا همین جا دست نگه دارید و اجازه دهید با این محیط دوست داشتنی و قابلیت‌های آن بعدا آشنا شویم.
در گام دوم به Visual Studio می‌رویم و نحوه ارتباط با پایگاه داده و استفاده از دستورات آن را فرا می‌گیریم.
 

گام دوم:

با یک پروژه Test شروع می‌کنیم که در هر گام تکمیل می‌شود و می‌توانید پروژه کامل را در پایان این پست دانلود کنید.

برای استفاده از کتابخانه‌های مورد نیاز دو راه وجود دارد:

  • استفاده از NuGet : با استفاده از دستور زیر Package مورد نیاز به پروژه شما افزوده می‌شود.

PM> Install-Package RavenDB -Version 1.0.919 

  • اضافه کردن کتابخانه‌ها به صورت دستی : کتابخانه‌های مورد نیاز شما در همان فایلی که دانلود شده بود و در پوشه Client قرار دارند.

کتابخانه هایی را که NuGet به پروژه من اضافه کرد، در تصویر زیر مشاهده می‌کنید :

با Newtonsoft.Json در اولین بخش بحث آشنا شدید. NLog هم یک کتابخانه قوی و مستقل برای مدیریت Log است که این پایگاه داده از آن بهره برده است.

" دلیل اینکه از پروژه تست استفاده کردم ؛ تمرکز روی کدها و مشاهده تاثیر آن‌ها ، مستقل از UI و لایه‌های دیگر نرم افزار است. بدیهی است که استفاده از آن‌ها در هر پروژه امکان پذیر است. "

برای شروع نیاز به آدرس Server و نام پایگاه داده داریم که می‌توانید در App.config به عنوان تنظیمات نرم افزار شما ذخیره شود و هنگام اجرای نرم افزار مقدار آن‌ها را خوانده و در متغییر‌های readonly ذخیره شوند.

<appSettings>
    <add key="ServerName" value="http://SorousH-HP:8080/"/>
    <add key="DatabaseName" value="TestDatabase" />
</appSettings>

هنگامی که صفحه Management Studio در مرورگر باز است، می‌توانید از نوار آدرس مرورگر خود آدرس سرور را به دست آورید.  

    [TestClass]
    public class BeginnerTest
    {
        private readonly string serverName;
        private readonly string databaseName;

        public BeginnerTest()
        {
            serverName = ConfigurationManager.AppSettings["ServerName"];
            databaseName = ConfigurationManager.AppSettings["DatabaseName"];
        }
    }

برای برقراری ارتباط با پایگاه داده نیاز به یک شئ از جنس DocumentStore و جهت انجام عملیات مختلف ( ذخیره، حذف و ... ) نیاز به یک شئ از جنس IDocumentSession است. کد زیر، نحوه کار با آن‌ها را به شما نشان می‌دهد :

[TestClass]
    public class BeginnerTest
    {
        private readonly string serverName;
        private readonly string databaseName;

        private DocumentStore documentStore;
        private IDocumentSession session;

        public BeginnerTest()
        {
            serverName = ConfigurationManager.AppSettings["ServerName"];
            databaseName = ConfigurationManager.AppSettings["DatabaseName"];
        }

        [TestInitialize]
        public void TestStart()
        {
            documentStore = new DocumentStore { Url = serverName };
            documentStore.Initialize();
            session = documentStore.OpenSession(databaseName);

        }
        
        [TestCleanup]
        public void TestEnd()
        {
             session.SaveChanges(); 
             documentStore.Dispose();
             session.Dispose();
        }
    }

در طراحی این پایگاه داده از اگوی Unit Of Work استفاده شده است. به این معنی که تمام تغییرات در حافظه ذخیره می‌شوند و به محض اجرای دستور ;()session.SaveChanges ارتباط برقرار شده و تمام تغییرات ذخیره خواهند شد.

هنگام شروع ( تابع : TestStart ) متغییر session مقدار دهی می‌شود و در پایان کار ( تابع : TestEnd ) تغییرات ذخیره شده و منابعی که توسط این دو شئ در حافظه استفاده شده است، رها می‌شود.

البته بر مبنای طراحی شما، دستور ;()session.SaveChanges می‌تواند پس از انجام هر عملیات اجرا شود.

برای آشنا شدن با نحوه ذخیره کردن اطلاعات، به کد زیر دقت کنید:
class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public int Zip { get; set; }اهی 
    }
        [TestMethod]
        public void Insert()
        {
            var user = new User
                           {
                               Id = 1,
                               Name = "John Doe",
                               Address = "no-address",
                               Zip = 65826
                           };
            session.Store(user);
        }
اگر همه چیز درست پیش رفته باشد، وقتی به محیط RavenDB Studio که هنوز در مرورگر شما باز است، نگاهی می‌اندازید، یک سند جدید ایجاد شده است که با کلیک روی آن، اطلاعات آن قابل مشاهده است.
لحظه‌ی لذت بخشی است...
یکی  از روش‌های خواندن اطلاعات هم به صورت زیر است:
        [TestMethod]
        public void Select()
        {
            var user = session.Load<User>(1);
        }
نتیجه خروجی این دستور هم یک شئ از جنس کلاس User است.

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

" به شما پیشنهاد می‌کنم که منتظر بحث بعدی نباشید! همین حالا دست به کار شوید... "


مطالب
نحوه‌ی صحیح فراخوانی 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 فوق را به آن‌ها اعمال کنید؛ در غیر اینصورت منتظر باشید تا روزی برنامه شما به سادگی کرش کند.