۱۳۸۹/۰۷/۱۵

معرفي Microsoft.Data.dll يا WebMatrix.Data.dll


مايكروسافت اخيرا علاوه بر تكميل ORM هاي خود مانند LINQ to SQL و همچنين Entity framework ، لايه ديگري را نيز بر روي ADO.NET جهت كساني كه به هر دليلي دوست ندارند با ORMs كار كنند و از نوشتن كوئري‌هاي مستقيم SQL لذت مي‌برند،‌ ارائه داده است كه Microsoft.Data library نام دارد و از قابليت‌هاي جديد زبان سي شارپ مانند واژه‌ كليدي dynamic استفاده مي‌كند.

در ادامه قصد داريم جهت بررسي توانايي‌هاي اين كتابخانه از بانك اطلاعاتي معروف Northwind استفاده كنيم. اين بانك اطلاعاتي را از اينجا مي‌توانيد دريافت كنيد.

مراحل استفاده از Microsoft.Data library:
الف) اين اسمبلي جديد به همراه پروژه WebMatrix ارائه شده است. بنابراين ابتدا بايد آن‌را دريافت كنيد: +
لازم به ذكر است كه اين كتابخانه اخيرا به WebMatrix.Data.dll تغيير نام يافته است. (اگر وب را جستجو كنيد فقط به Microsoft.Data.dll اشاره شده است)

ب) پس از نصب، ارجاعي را از اسمبلي WebMatrix.Data.dll به پروژه خود اضافه نمائيد. اين اسمبلي در صفحه‌ي Add References ظاهر نمي‌شود و بايد كامپيوتر خود را براي يافتن آن جستجو كنيد كه عموما در آدرس زير قرار دارد:
C:\Program Files\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies\WebMatrix.Data.dll

ج) اتصال به بانك اطلاعاتي
پيش فرض اصلي اين كتابخانه بانك اطلاعاتي SQL Server CE است. بنابراين اگر قصد استفاده از پروايدرهاي ديگري را داريد بايد به صورت صريح آن‌را ذكر نمائيد:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="systemData:defaultProvider" value="System.Data.SqlClient" />
</appSettings>
<connectionStrings>
<add name="Northwind"
connectionString="Data Source=(local);Integrated Security = true;Initial Catalog=Northwind"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>

اين تعاريف در فايل web.config و يا app.config برنامه وب يا ويندوزي شما قرار خواهند گرفت.

د) نحوه‌ي تعريف كوئري‌ها و دريافت اطلاعات
using System;
using WebMatrix.Data;

namespace TestMicrosoftDataLibrary
{
class Program
{
static void Main(string[] args)
{
getProducts();

Console.Read();
Console.WriteLine("Press a key ...");
}

private static void getProducts()
{
using (var db = Database.Open("Northwind"))
{
foreach (var product in db.Query("select * from products where UnitsInStock < @0", 20))
{
Console.WriteLine(product.ProductName + " " + product.UnitsInStock);
}
}
}
}
}
پس از افزودن ارجاعي به اسمبلي WebMatrix.Data و مشخص سازي رشته‌ي اتصالي به بانك اطلاعاتي، استفاده از آن جهت دريافت اطلاعات كوئري‌ها همانند چند سطر ساده‌ي فوق خواهد بود كه از امكانات dynamic زبان سي شارپ 4 استفاده مي‌كند؛ به اين معنا كه product.ProductName و product.UnitsInStock در زمان اجرا مورد ارزيابي قرار خواهند گرفت.
همچنين نكته‌ي مهم ديگر آن نحوه‌ي تعريف پارامتر در آن است (همان 0@ ذكر شده) كه نسبت به ADO.NET كلاسيك به شدت ساده شده‌است (و نوشتن كوئري‌هاي امن و SQL Injection safe را تسهيل مي‌كند).
در اينجا Database.Open كار گشودن name ذكر شده در فايل كانفيگ برنامه را انجام خواهد داد. اگر بخواهيد اين تعاريف را در كدهاي خود قرار دهيد (كه اصلا توصيه نمي‌شود)، مي‌توان از متد Database.OpenConnectionString استفاده نمود.

يا مثالي ديگر: استفاده از LINQ حين تعريف كوئري‌ها:
private static void getCustomerFax()
{
using (var db = Database.Open("Northwind"))
{
var product = db.Query("SELECT * FROM [Customers] WHERE City=@0", "Paris").FirstOrDefault();
if (product != null)
Console.WriteLine(product.Fax);
else
Console.WriteLine("not found.");
}
}

ه) اجراي كوئري‌ها بر روي بانك اطلاعاتي
private static void ExecQuery()
{
using (var db = Database.Open("Northwind"))
{
int affectedRecords = db.Execute("UPDATE [Customers] SET fax = fax + '*' WHERE City = @0", "Paris");
Console.WriteLine("Affected records: {0}", affectedRecords);
}
}

با استفاده از متد Execute آن مي‌توان كوئري‌هاي دلخواه خود را بر روي بانك اطلاعاتي اجرا كرد. خروجي آن تعداد ركورد تغيير كرده است.

و) نحوه‌ي اجراي يك رويه ذخيره شده و نمايش خروجي آن
private static void ExecSPShowResult()
{
using (var db = Database.Open("Northwind"))
{
var customer = db.Query("exec CustOrderHist @0", "ALFKI").FirstOrDefault();
if (customer != null)
{
Console.WriteLine(customer.ProductName);
}
}
}
در اين مثال رويه ذخيره شده CustOrderHist در بانك اطلاعاتي Northwind اجرا گرديده و سپس اولين خروجي آن نمايش داده شده است.

ز) اجراي يك تابع و نمايش خروجي آن
private static void useFuncs()
{
using (var db = Database.Open("Northwind"))
{
var query = db.Query("SELECT dbo.FN_GET_CATEGORY_TREE(@0) as Rec1", 3);
foreach(var tree in query)
{
Console.WriteLine(tree.Rec1);
}
}
}
در اينجا تابع FN_GET_CATEGORY_TREE موجود در بانك اطلاعاتي Northwind انتخاب گرديده و سپس خروجي آن به كمك يك نام مستعار (براي مثال Rec1) نمايش داده شده است.

سؤال : آيا WebMatrix.Data.dll بهتر است يا استفاده از ORMs ؟

در اينجا چون از قابليت‌هاي دايناميك زبان سي شارپ 4 استفاده مي‌شود، كامپايلر دركي از اشياء خروجي و خواص آن‌ها براي مثال tree.Rec1 (در مثال آخر) ندارد و تنها در زمان اجرا است كه مشخص مي‌شود آيا يك چنين ستوني در خروجي كوئري وجود داشته است يا خير. اما حين استفاده از ORMs اين طور نيست و Schema يك بانك اطلاعاتي پيشتر از طريق نگاشت‌هاي جداول به اشياء دات نتي، به كامپايلر معرفي مي‌شوند و همين امر سبب مي‌شود تا اگر ساختار بانك اطلاعاتي تغيير كرد، پيش از اجراي برنامه و در حين كامپايل بتوان مشكلات را دقيقا مشاهده نمود و سپس برطرف كرد.
ولي در كل استفاده از اين كتابخانه نسبت به ADO.NET كلاسيك بسيار ساده‌تر بوده، مي‌توان اشياء و خواص آن‌ها را مطابق نام جداول و فيلدهاي بانك اطلاعاتي تعريف كرد و همچنين تعريف پارامترها و برنامه نويسي امن نيز در آن بسيار ساده‌تر شده است.

براي مطالعه بيشتر:
Introduction to Microsoft.Data.dll