پیادهسازی LINQ to SQL به شیوه کدنویسی
در شماره گذشته مشاهده کردید که چگونه میتوان به بانکهای اطلاعاتی متصل شد و جداول مورد نیاز را با استفاده از ابزارها و ویزاردهایی که ویژوال استودیو بهطور آماده در اختیار برنامهنویسان قرار میدهد، در برنامه کاربردی وارد و از آنها استفاده کرد. اما در بعضی موارد برنامهنویسان مجبور هستند جداول مورد نیاز را به شیوه برنامهنویسی در یک برنامه کاربردی وارد کنند. بر همین اساس، در این بخش از مقاله در نظر داریم نحوه دسترسی به بانکهای اطلاعاتی را بدون استفاده از پنجرههای آماده ویژوال استودیو و بهشکل دستی به شما نشان دهیم. (بانک اطلاعاتی مورد استفاده در این مقاله همان بانک اطلاعاتی AdventureWorks است که در شماره گذشته از آن استفاده کردیم).
محاوره چهارده، اضافه کردن یک جدول در قالب یک کلاس در برنامه
به نظر من یکی از بهترین ویژگیهایی که لینک در اختیار برنامهنویسان قرار میدهد، تعریف جداول بانک اطلاعاتی همانند کلاسها در یک برنامه کاربردی است. یکی از قابلیتهای جالبی که در زمان کدنویسی میتوانید از آن بهره ببرید، تعریف جداول بانک اطلاعاتی همانند یک کلاس در یک برنامه کاربردی است که تحت عنوان Entity از آن نام برده میشود. در زمان تعریف کلاسها در برنامههای کاربردی خصلت ویژهای تحت عنوان Table که از اشیای LINQ To SQL است وجود دارد که با استفاده از آن نام جدول مورد نظر را میتوان تعیین کرد. ترکیب نحوی نشان داده شده در فهرست 1، نحوه تعریف کلاسی به نام MyTestTable را نشان میدهد. MyTestTable همان جدولی است که در مثال شماره گذشته آن را ایجاد کردهایم.
فهرست 1
[Table(Name = “MyTestTable”)]
public class MyTestTable
{
public int MytableID;
public string TablelName;
}
خصلت Table فیلدی بهنام Name دارد که برای تعیین نام دقیق جدول در بانک اطلاعاتی مورد استفاده قرار میگیرد. اگر از این فیلد استفاده نکنید، LINQ to SQL تصور میکند نام کلاس هماهنگ با نام جدول بانک اطلاعاتی تعیین شده است. بنابراین، در تعریف نام کلاس مجبور نیستید نام دقیق جدول را بیان کنید، در نتیجه این انتخاب را دارید تا نام مورد نظر خود را وارد کنید. کلاسهایی که به این شکل تعریف میشوند، Entity Classes نام دارند. در گام بعد باید اعضای کلاس را مشخص کنید. این اعضا در واقع ستونهایی هستند که تمایل دارید دادههای آنها را دریافت کنید. در زمان تعریف این فیلدها حتماً به یکسان بودن نوع آنها با نوع ستونها در بانک اطلاعاتی توجه کنید. خصلت Column به شما اجازه تعریف ستونها را میدهد. فهرست 2 نحوه تعریف ستونها را نشان میدهد.
فهرست 2
[Table(Name = “ MyTestTable”)]
public class MyTestTable
{
[Column(IsPrimaryKey = true)]
public int MytableID;
[Column]
public string TablelName;
}
خصلت Column تعدادی فیلد دارد که یک سری پارامتر را بهعنوان ورودی دریافت میکند. در نتیجه به برنامهنویس اجازه میدهد ستونها را با جزییترین خصلتها تعریف کند. بهطور مثال، خاصیت مهمIsPrimaryKey بهمنظور مشخص کردن کلید اصلی که در یک جدول تعریف شده است، مورد استفاده قرار میگیرد.
کلاس DataContext
یکی از مهمترین کلاسهایی که به شما اجازه میدهد با اشیای بانک اطلاعاتی کار کرده و تغییراتی را روی آنها پیادهسازی کنید، کلاس DataContext است. متدها، خاصیتها و فیلدهایی که این کلاس در اختیار شما قرار میدهند، بهراحتی امکان کار کردن با عناصر یک بانک اطلاعاتی را فراهم میکنند. بهطور معمول، این کلاس بهصورت یک کلاس مشتق شده مورد استفاده قرار میگیرد، اما به طور مستقیم نیز میتواند استفاده شود.
این کلاس شبیه به شیء Connection در ADO.Net مورد استفاده قرار میگیرد. DataContext با استفاده از یک شیء ارتباطی به بانک اطلاعاتی هدف وصل میشود. این شیء ارتباطی میتواند نام فایل یا یک رشته ارتباطی باشد. DataContext با استفاده از عملگرهای مشخصی همچون Where و Select محاورههای مورد نیاز کاربر را ایجاد و آنها را مدیریت میکند.
جداول در قالب کلاسها
همان گونه که در پاراگراف قبل مشاهده کردید، جداول بهشکل ساده و کاربردی در قالب کلاسهایی میتوانند در اختیار شما قرار گیرند. کلاسهایی که به این شکل ترسیم شده و فیلدهای متناظر به جدولها بانک اطلاعاتی را توصیف میکنند به شما اجازه میدهند بهراحتی به رکوردها دسترسی داشته باشید و تغییرات مورد نظر خود را پیادهسازی کنید.
محاوره پانزده؛ اضافه کردن رکوردها به یک جدول بر مبنای تکنیک موجودیت فهرست 3 نحوه بهکارگیری کلاس DataContext روی بانک اطلاعاتی AdventureWorks2012 را نشان میدهد. در حال حاضر به دلیل اینکه هیچگونه رکوردی در جدول MyTestTable وجود ندارد، خروجی قطعه کد فوق خالی خواهد بود. (ما جدول MyTestTable را در آخرین محاورهای که در شماره گذشته ماهنامه مورد بررسی قرار دادیم ایجاد کردیم.) در زمان نوشتن کدهای فوق دقت کنید فضاهای نام را در برنامه خود وارد کنید.
فهرست 3
using System.Linq;
using System.Data.Linq.Mapping;
using System.Data.Linq;
class Program
{
[Table(Name = “MyTestTable”)]
public class MyTestTable
{
[Column(IsPrimaryKey = true)]
public int MytableID;
[Column]
public string TablelName;
}
static void Main(string[] args)
{
String connectionString =
“Data Source=APPLE-PC\\MSSQLSERVER1;Initial Catalog=AdventureWorks2012;Integrated Security=True”;
DataContext dc = new DataContext(connectionString);
Table<MyTestTable> mytable = dc.GetTable<MyTestTable>();
var q =
from c in mytable
//where c.MytableID == 1
select c;
foreach (var query in q)
Console.WriteLine(“id = {0}, Content = {1}”, query.MytableID, query.TablelName);
}
}
محاوره شانزده، تعریف نمونهای از کلاس DataContext در قالب یک نوع Strongly Typed (وابستگی زیاد به نوع)
هر جدول بانک اطلاعاتی در داتنت بهعنوان یک شیء Table شناخته میشود. این شیء از طریق متد GetTable() که در هر کلاسی وجود دارد، در اختیار برنامهنویسان قرار دارد. اما پیشنهاد میکنیم بهجای آنکه DataContext را بهطور مستقیم و با استفاده از متد GetTable() مورد استفاده قرار دهید، از تکنیک وابستگی زیاد به نوع در ارتباط با کلاس DataContext استفاده کنید. در این تکنیک تمام جداول به عنوان عضوی از کلاس تعریف میشوند و در نتیجه دسترسی آسان به جداول بانک اطلاعاتی را فراهم میکنند. قطعه کد فهرست4 نحوه تعریف جدولها Person، PersonPhone و MyTestTable را برمبنای این تکنیک نشان میدهد.
فهرست 4
class Program
{
[Table(Name = “MyTestTable”)]
public class MyTestTable
{
[Column(IsPrimaryKey = true)]
public int MytableID;
[Column]
public string TablelName;
}
[Table(Name = “Person.Person”)]
public class Person
{
[Column(IsPrimaryKey = true)]
public int BusinessEntityID;
[Column]
public string FirstName;
[Column]
public string Title;
[Column]
public string LastName;
[Column]
public DateTime ModifiedDate;
}
[Table(Name = “Person.PersonPhone”)]
public class PersonPhone
{
[Column(IsPrimaryKey = true)]
public int BusinessEntityID;
[Column]
public string PhoneNumber;
[Column]
public int PhoneNumberTypeID;
[Column]
public DateTime ModifiedDate;
}
public partial class AdventureWorks2012 : DataContext
{
public Table<MyTestTable> mytable;
public Table<Person> Person;
public Table<PersonPhone> PersonPhone;
public AdventureWorks2012(string connection) : base(connection) { }
}
اکنون میتوانید از یک ترکیب سادهتر و ساختیافتهتر در ارتباط با جدولها مطابق با آنچه در فهرست 5 نشان داده شده است، استفاده کنید. (در زمان کار با بانکهای اطلاعاتی همواره به این نکته توجه داشته باشید که در هر لحظه احتمال پدید آمدن یک استثنا وجود دارد، در نتیجه همیشه کدهای خود را در بلوکهای try/catch قرار دهید. در فهرست 5 به دلیل اینکه جدول فوق هیچگونه رکوردی ندارد یک استثنا را نشان میدهد.)
فهرست 5
static void Main(string[] args)
{
String connectionString =
“Data Source=APPLE-PC\\MSSQLSERVER1;Initial Catalog=AdventureWorks2012;Integrated Security=True”;
AdventureWorks2012 dc = new AdventureWorks2012(connectionString);
try
{
MyTestTable query = (from c in dc.mytable
where c.MytableID == 1
select c).Single<MyTestTable>();
Console.WriteLine(“ID is:{0} ، Table name is:{1}”, query.MytableID، query.TablelName);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
محاوره هفده، اضافه کردن رکوردهایی به یک جدول
برنامههای خیلی کمی تنها بهمنظور دریافت دادهها مورد استفاده قرار میگیرند. اکثر برنامههای کاربردی به ویرایش دادهها و اضافه کردن دادهها نیاز دارند. فهرست 6 نحوه اضافه کردن رکوردی به جدول MyTestTable و بهروزرسانی بانک اطلاعاتی را نشان میدهند. تنها نکتهای که در ارتباط با این فهرست باید به آن توجه کنید این است که در آخرین گام باید متد SubmitChanges از کلاس DataContext را برای ثبت تغییرات روی بانک اطلاعاتی فراخوانی کنید.
فهرست 6
Static void Main(string[] args)
{
String connectionString =
“Data Source=APPLE-PC\\MSSQLSERVER1;Initial Catalog=AdventureWorks2012;Integrated Security=True”;
AdventureWorks2012 dc = new AdventureWorks2012(connectionString);
MyTestTable mtable = new MyTestTable
{
MytableID = 1،
TablelName = “Inserted by Linq”
};
dc.mytable.InsertOnSubmit(mtable);
dc.SubmitChanges();
MyTestTable myquery = dc.mytable.Where(c => c.TablelName == “Inserted by Linq”).First();
Console.WriteLine(“{0} – {1}”, myquery.MytableID، myquery.TablelName);
}
همان گونه که مشاهده میکنید نحوه اضافه کردن رکوردها در لینک سادهتر از آن است که تصور میشد. در این روش دیگر نیاز نیست اشیای مختلفی مانند DataAdapter یا تدارکبینندههای مختلفی که در ADO.Net مورد استفاده قرار میگیرند را فراخوانی کنید. در فهرست 6 ما کارهای زیر را انجام دادیم:
1- ابتدا نمونهای از کلاس AdventureWorks2012 را تعریف کردیم.
2- در مرحله دوم یک شیء از کلاس MyTestTable تعریف و این شیء را مقداردهی کردیم.
3- در مرحله سوم شیء ساخته شده را به جدول MyTestTable که از نوع Table<MyTestTable> بود و در کلاس AdventureWorks2012DataContext قرار داشت، اضافه کردیم.
4- در چهارمین مرحله متد SubmitChanges را برای ثبت تغییرات در بانک اطلاعاتی فراخوانی کردیم. همچنین، برای آنکه اطمینان حاصل کنیم رکورد مورد نظر بهدرستی در جدول اضافه شده است، بر مبنای رکورد اضافه شده محاورهای را نوشتیم.
محاوره هجده، نحوه دریافت رکوردهایی از یک جدول بر مبنای تکنیک Strongly Typed
اگر در نظر داشته باشید تا محاورههای مورد نیاز خود را تعریف کنید، این کار بهسادگی انجام میشود. فهرست 7 رکوردهای اطلاعاتی موجود در دو جدول Mytable و Person را دریافت میکند.
فهرست 7
static void Main(string[] args)
{
String connectionString =
“Data Source=APPLE-PC\\MSSQLSERVER1;Initial Catalog=AdventureWorks2012;Integrated Security=True”;
AdventureWorks2012 dc = new AdventureWorks2012(connectionString);
var q =
from c in dc.mytable
from a in dc.Person
where a.BusinessEntityID== 1
where c.MytableID== 1
select new { c, a };
foreach (var query in q)
{
Console.WriteLine(“ID = {0}, First Name = {1}”,
query.c.MytableID, query.c.TablelName);
Console.WriteLine(“ID = {0}, First Name = {1}, Last Name= {2} , Date={3}”,
query.a.BusinessEntityID, query.a.FirstName, query.a.LastName, query.a.ModifiedDate);
}
Console.WriteLine(“This query returned {0} records”,q.Count());
}
محاوره نوزده، حذف رکوردهایی از یک جدول
در کنار اضافه کردن رکوردها به یک جدول، حذف رکوردها از یک جدول نیز از اهمیت خاصی برخوردار است. حذف رکوردها با فراخوانی متد DeleteOnSubmit که محاورهای را بهعنوان پارامتر ورودی دریافت میکند، انجام میشود. در فهرست 8 به دنبال رکوردهایی هستیم که فیلد MytableID آنها برابر با 1 است. اگر چنین رکوردهایی در جدول پیدا شوند، از بانک اطلاعاتی حذف خواهند شد.
فهرست 8
static void Main(string[] args)
{
String connectionString =
“Data Source=APPLE-PC\\MSSQLSERVER1;Initial Catalog=AdventureWorks2012;Integrated Security=True”;
AdventureWorks2012 dc = new AdventureWorks2012(connectionString);
try
{
var delRecord = (from p in dc.mytable
where p.MytableID == 1
select p).FirstOrDefault();
if (delRecord != null)
dc.mytable.DeleteOnSubmit(delRecord);
dc.SubmitChanges();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
محاوره بیست، بهروزرسانی رکوردهای یک جدول
دادههای مرتبط با ستونهای یک جدول بهراحتی از طریق محاورههای لینک بهروزرسانی میشوند. در این حالت جستوجو بهمنظور پیدا کردن رکوردهای مورد نظر انجام میشود. اگر رکوردها پیدا شدند، مقادیر جدید جایگزین مقادیر قبلی میشوند. فهرست 9 نحوه بهروزرسانی رکورد جدول MyTable که فیلد MyTableID آن برابر با مقدار 1 است نشان میدهد. در این قطعه کد فیلد TableName مقدار جدید را دریافت کرده است و متد SubmitChanges تغییرات را ثبت میکند.
فهرست 9
static void Main(string[] args)
{
String connectionString =
“Data Source=APPLE-PC\\MSSQLSERVER1;Initial Catalog=AdventureWorks2012;Integrated Security=True”;
AdventureWorks2012 ad = new AdventureWorks2012(connectionString);
var cust = ad.mytable.Single(c => c.MytableID== 1);
cust.TablelName = “Hi everyone”;
Console.WriteLine(cust.TablelName);
ad.SubmitChanges();
}
دسترسی منطبق با استانداردهای جهانی به دادهها از طریق LINQ to XML
در میان فناوریهای مختلفی که امروزه مورد استفاده قرار میگیرد، فناوری XML به عنوان یک استاندارد جامع برای قالببندی دادهها از سوی سازمانهای بزرگ مورد استفاده قرار میگیرد. با توجه به فراگیر بودن این استاندارد و کاربردی بودن این فناوری، مایکروسافت چارچوب جامعی را برای دسترسی به دادههایی که درون فایلهای XML قرار دارند طراحی کرده است. این چارچوب جامع با فضای نام LINQ to XML در اختیار برنامهنویسان قرار دارد. تا پیش از معرفی لینک از سوی مایکروسافت، برنامهنویسان داتنت از طریق اسمبلی System.Xml.dll قادر به دستکاری اسناد XML بودند. این کتابخانه به برنامهنویسان اجازه میداد بهراحتی به تعامل با دادههای XML بپردازد، اسناد XML داخل حافظه را بارگذاری کند، یک سند XML را برای گرههای ویژه جستوجو کند، یک سند را بر مبنای یک الگوی مشخص اعتبارسنجی کند و کارهای مشابه را انجام دهد. هرچند این کتابخانه طیف گستردهای از قابلیتها را در اختیار برنامهنویسان قرار میداد، اما بهکارگیری متدهای آن بهراحتی امکانپذیر نبود.
اما LINQ to XML یک رابط برنامهنویسی مقیم در حافظه را در اختیار برنامهنویس قرار میدهد تا از طریق زبانهای برنامهنویسی داتنت بهراحتی بتواند با فایلهای XML کار کند. محاورههای پیچیدهای که با استفاده از LINQ to XML قادر به نوشتن آنها هستید، این پتانسیل را دارند تا دادهها از منابع دادهای مختلفی در یک زمان دریافت کنند. در حالی که در ظاهرLINQ to XML عملکردی شبیه به DOM (سرنام Document Object Model) دارد، اما تفاوتهایی با آن دارد. بهطور مثال، یک نمونه شیء را به شکل ساده و سریعی ایجاد میکند. در نتیجه برنامهنویسان بهراحتی میتوانند از آن استفاده کنند. مهمترین مزیت LINQ to XML به یکپارچگی این کتابخانه با لینک باز میگردد. در نتیجه بهراحتی امکان نوشتن محاورهها با استفاده از مجموعهای از عناصر و خصلتها امکانپذیر است. همین موضوع باعث میشود تا توانمندی محاورههای لینک همتراز با XPath و XQuery باشند. مزیت دیگر LINQ to XML به انعطافپذیری بالای آن باز میگردد که به برنامهنویس اجازه میدهد نتایج تولید شده را در قالب پارامترهایی برای اشیای XElement و XAttribute مورد استفاده قرار دهد، به طوری که امکان ساخت درختهای XML را امکانپذیر میسازد. این قابلیت که بهنام ساختیافتگی تابعی مشهور است به طراحان اجازه میدهد با سهولت هرچه تمامتر درختهای XML را از شکلی به شکل دیگر تغییر دهند.
کتابخانه System.Xml.Linq هر آنچه به آن نیاز دارید را در اختیارتان قرار میدهد
System. Xml.Linq.dll مشتمل بر سه کتابخانه متمایز از یکدیگر است که برای کار کردن با XML مورد استفاده قرار میگیرد. System.Xml.Linq، System.Xml.Schema و System.Xml.Path همراه با کتابخانه اصلی System.Xml.Linq مشتمل بر کلاسهایی هستند که برای کار کردن با اسناد لینک به آنها نیاز دارید.
محاوره بیست و یک، نحوه ساخت یک درخت XML با لینک
ساخت یک درخت XML یکی از رایجترین کارهایی است که برنامهنویسان انجام میدهند. بهطور مثال، برنامهای دادههایی تولید کرده و باید این دادهها را در قالب یک سند XML به کاربران نشان دهد. لینک با استفاده از کلاس XElement امکان پیادهسازی این وظیفه را فراهم میکند. این کار به دو شکل انجام میشود. در روش سادهتر یک شیء از کلاس XElement که عنصر ریشه را تعریف میکند، ساخته شده و در ادامه گرههای فرزند و خصلتها با تعریف نمونههایی از XElement و XAttribute ساخته میشوند. در ادامه یک شیء از XDocument همراه با XDeclaration تعریف شده و عناصر XElement به آن افزوده میشوند. فهرست 10 نحوه انجام این کار را نشان میدهد.
فهرست 10
static void Main(string[] args)
{
XElement root = new XElement(“Programming”,
new XElement(“Group”, new XAttribute(“ID”, 1),
new XElement(“VisualBasic”),
new XElement(“FSharp”, “Its a powerful language programming of .Net’s family.”),
new XElement(“Group2”, new XAttribute(“ID”, 2),
new XElement(“CPlusPlus”, “Its a powerful language programming .”),
new XElement(“JAVA”),
new XElement(“Rate”, 1),
new XElement(“Rich”, true))));
XDocument doc = new XDocument(
new XDeclaration(“1.0”, “”, “”), root);
doc.Save(Console.Out);
خروجی فهرست 10 را در شکل 1 مشاهده میکنید.
شکل ۱
اگر تمایل دارید این خروجی را در قالب یک فایل XML در اختیار داشته باشید، از دستور doc.Save استفاده کنید. در این حالت بهجای آنکه خروجی روی صفحهنمایش ظاهر شود، در فایلی که آن را مشخص کردهاید، قرار میگیرد. در شماره آینده ادامه مبحث LINQ to XML را ادامه خواهیم داد.
ماهنامه شبکه را از کجا تهیه کنیم؟
ماهنامه شبکه را میتوانید از کتابخانههای عمومی سراسر کشور و نیز از دکههای روزنامهفروشی تهیه نمائید.
ثبت اشتراک نسخه کاغذی ماهنامه شبکه
ثبت اشتراک نسخه آنلاین
کتاب الکترونیک +Network راهنمای شبکهها
- برای دانلود تنها کتاب کامل ترجمه فارسی +Network اینجا کلیک کنید.
کتاب الکترونیک دوره مقدماتی آموزش پایتون
- اگر قصد یادگیری برنامهنویسی را دارید ولی هیچ پیشزمینهای ندارید اینجا کلیک کنید.
نظر شما چیست؟