khaledbelal
03-11-2010, 04:05 PM
بسم الله الرحمن الرحيم .
السلام عليكم ورحمة الله وبركاته .
في الدرس السابق تعرفنا على اساسيات LINQ ، سنواصل في درسنا هذا استخدام التطبيقات المختلفة في هذه التقنية .
*** تذكير سريع : المتغيرات غير المعرفة :
احياناً تقوم بعمل جملة استعلام يكون الناتج فيها فئة لم تقم بتعريفها من قبل ، هذه هي واحدة من فوائد تقنية Implicitly Typed Local Variables التي تم شرحها سابقاً ، هذه الجملة كمثال :
var subset =
from i in numbers
where i < 10
select i;
*** تذكير آخر : استخدام Lambda Expressions مع LINQ :
تذكر أن باستطاعات استخدام تعبيرات لامبادا Lambda Expressions بدلاً من كتابة استعلام LINQ بالطريقة العادية .
ذكرنا في أول دروسناً ثلاث أنواع لل LINQ .
1- LINQ TO DATAET :
ال dataset كما اسلفنا تشكل صورة أو نسخة من قاعدة البيانات في الذاكرة ، لذا فهي بكل بساطة نقطة جيدة لنستخدم عليها استعلامات LINQ الخاصة بنا .
هذا الدرس للاستاذ محمد سامر سلو فيه تفصيل جيد لهذا الموضوع .
http://vb4arab.com/vb/showthread.php?t=12294
2- LINQ TO XML :
درس آخر للاستاذ محمد سامر حول هذا الموضوع .
http://vb4arab.com/vb/showthread.php?t=9126
أما النوع الثالث فسنفرد له موضوعاً مستقلاً هو آخر مواضيعنا حول LINQ في الدرس القادم .
3- LINQ TO SQL :
فئة من فئات LINQ موجهة خصيصاً لدعم SQL Server ، في العادة هي الأكثر استخداما وسنحاول التعرف عليها سريعاً في هذا الدرس .
- البحث والاستعلام :
تعرفنا عليه سابقاً ، هذا المثال مثلاً لاعادة الاسم وتاريخ التخرج على شكل فئة جديدة للأشخاص الذين يزيد عمرهم عن 30 سنة ويقطنون في مصر :
var query = from c in Employee
where c.Age > 30
&&
c.Countery == "Egypt"
Select new { c.Name, c.GraduationDate};
- استدعاء Stored Procedures :
كل ما عليك هو فقط تعريف دالة تشابه Procedure لها نفس ال Attributes ، وهي ما يقوم بها الفيجوال ستوديو افتراضياً ، الآن كل ما عليك هو كتابة أمر بهذا الشكل ( استعلام يستقبل متغير واحد ) :
var c = db.ProceduresName("Egypt");
- Compiled Query :
إذا كان هناك جملة استعلام ستستخدمها لعدة مرات فليس من المنطقي جعل نظام قواعد البيانات يتعرف من جديد على الاستعلام كل مرة ، لذا توفر لنا نظم قواعد البيانات الحل لهذه النقطة ، أيضاً LINQ تقدم لنا ذات النظرية عبر ما يسمى باسم Compiled Query .
فكرة ال Compiled Query ببساطة تعتمد على استخدام دالة CompiledQuery.Compile لعمل Compile لجملة الاستعلام ، الشكل التالي كمثال :
var c = CompiledQuery.Compile(
( DataContext context, string counteryName, int age) =>
from c in Employee
where c.Age > age
&&
c.Countery == counteryName
select new { c.CustomerID, c.CompanyName, c.City } );
والآن يمكنك تجربة استخدامها لأكثر من مرة بتغيير البارميتر فقط ، والبحث في الاستعلام الذي تم عمل Compile له :
foreach ( var row in query(dc, "Egypt",22))
{
}
foreach ( var row in query(dc, "USA",28))
{
}
foreach ( var row in query(dc, "Saudi",38))
{
}
استخدام دوال في جملة الاستعلام :
لو فرضنا جملة الاستعلام التالية :
SELECT SUM( emp.salary ) AS TotalSalary FROM Employee emp Join Department dem ON emp.DepartmentID = dep.ID Group By dep.ID
نستطيع كتابتها بشكل LINQ بالشكل التالي :
var c =
from emp in db.Employee
join dep in db.Department
on emp.DepartmentID equals dep.ID
into TotalSalary
select TotalSalary.Sum( emp => emp.Salary );
استخدام جمل الاستعلام داخل LINQ :
قد تجد نفسك مضطراً احياناً لاستخدام واحدة من مميزات جمل الاستعلام التقليدية مثل الأمر PIVOT ، على كل هذه هي الصيغة العام لتنفيذ جملة SQL داخل ال LINQ :
- مثال منقول - :
var query = db.ExecuteQuery<EmployeeInfo>(@" With EmployeeHierarchy (EmployeeID, LastName, FirstName, ReportsTo, HierachyLevel) AS ( SELECT EmployeeID, LastName, ForstName, ReportsTo, 1 as HierarchyLevel FROM Employees WHERE ReportsTo IS NULL UNION ALL SELECT e.EmployeeID, e.LastName, e.FirstName, e.ReportsTo, eh.HierarchyLevel + 1 AS HierarchyLevel FROM Emplyees e INNER JOIN EmployeeHierarchy eh ON e.ReportsTo = eh.EmplyeeID ) SELECT * FROM EmployeeHierarchy ORDER BY HierarvhyLevel, LastName, FirstName" );
استخدام Inseret في LINQ:
var NewEmp = new Employee { [First Name] = "Ahmed", Age = 25, Countery="Egypt"};
db.Employee.Add( NewEmp );
في المثال السابق قمنا باضافة موظف جديد باسم أحمد وبعمر 25 سنة ومن مصر .
استخدام Update :
var EditEmp = db.Employee.Single
( c => c.Countery == "Egypt" );
EditEmp.Age = 30
في المثال السابق قمنا بالتعديل لعمر كل الاشخاص من مصر ليصبح 30 سنة .
استخدام Delete :
var deleteEmp = db.Employee.Single
( c => c.Age > 50 );
db.Employee.Remove( deleteEmp );
في المثال السابق قمنا بحذف الموظفين الذين تزيد اعمارهم عن 50 سنة .
SubmitChanges:
بعد اي عملية للاضافة أو للحذف أو التعديل لا بد من استدعاء الدالة db.SubmitChanges() لتفعيل التغييرات في قاعدة البيانات .
التحديث بالتزامن في قاعدة البيانات :
*** ال LINQ تتعامل بالوضع المنفصل وليس المتصل ، لذا ستجد له الكائن ChangeConflictExeption والذي ينتج عن تعارض عمليات التعديل على قاعدة البيانات بين عدة مستخدمين ، يمكن استعراض رسالة الخطأ بالشكل التالي :
try
{
Db2.SubmitChanges();
Break;
}
Catch ( ChangeConflictExeption ex)
{
MessageBox.Show( ex.Message );
Db2.*******( somequery, *******Mode.KeepChanges );
}
هنا يحاول الاستعلام التنفيذ ، لو لم يستطع يظهر رسالة الخطأ ويحاول مع أمر ******* مرة أخرى .
يمكن ايضاً في الأمر SubmitChanges تحديد سلوك البرنامج في حالة حدوث تعارض مثل الشكل التالي :
Db.SubmitChanges(ConflictMode.FailOnFirstConflict) ;
Db.SubmitChanges(ConflictMode.ContinueOnConflict);
وذلك من الفئة ConflictMode والتي لا تحتوي سوى على هذين العنصرين .
انشاء فئات LINQ TO SQL من خلال الفيجوال ستوديو :
يمكنك الفيجوال ستوديو 2008 من انشاء LINQ TO SQL Classes يمكنك التحكم بها لاحقاً ، من الشاشة الأولى :
http://vb4arab.com/vb/uploaded/3/01217411271.jpg
بعد اختياره ، يمكنك انشاء علاقات وجداول جديدة او سحب قاعدة بيانات من ال Server Explorer ، لذا قم بفتح قاعدة البيانات الخاصة بنا وقم بالبدء بسحب الجداول ، ستجد الشكل العام التالي :
http://vb4arab.com/vb/uploaded/3/11217411271.jpg
الآن بكل بساطة ستلاحظ ان الفيجوال ستوديو قام بمساعدتك في انشاء Data Access Layer - لو كنت تتذكرها - ، ستجد تعريفات للدوال التالية مثلاً :
partial void InsertEmployee_info(Employee_info instance);
partial void UpdateEmployee_info(Employee_info instance);
partial void DeleteEmployee_info(Employee_info instance);
الآن يمكنك كتابة كود كل منها لتسهيل الأمر لاحقاً على باقي مطورين الفريق ...
إلى هنا تكون دروسنا المتعلقة ب LINQ وما يتبعها من قواعد البيانات قد انتهت ، ربما نعود لقواعد البيانات بصورة مبسطة مرة اخرى مع دروس الويب .
والله الموفق ...
والسلام عليكم ورحمة الله وبركاته .
السلام عليكم ورحمة الله وبركاته .
في الدرس السابق تعرفنا على اساسيات LINQ ، سنواصل في درسنا هذا استخدام التطبيقات المختلفة في هذه التقنية .
*** تذكير سريع : المتغيرات غير المعرفة :
احياناً تقوم بعمل جملة استعلام يكون الناتج فيها فئة لم تقم بتعريفها من قبل ، هذه هي واحدة من فوائد تقنية Implicitly Typed Local Variables التي تم شرحها سابقاً ، هذه الجملة كمثال :
var subset =
from i in numbers
where i < 10
select i;
*** تذكير آخر : استخدام Lambda Expressions مع LINQ :
تذكر أن باستطاعات استخدام تعبيرات لامبادا Lambda Expressions بدلاً من كتابة استعلام LINQ بالطريقة العادية .
ذكرنا في أول دروسناً ثلاث أنواع لل LINQ .
1- LINQ TO DATAET :
ال dataset كما اسلفنا تشكل صورة أو نسخة من قاعدة البيانات في الذاكرة ، لذا فهي بكل بساطة نقطة جيدة لنستخدم عليها استعلامات LINQ الخاصة بنا .
هذا الدرس للاستاذ محمد سامر سلو فيه تفصيل جيد لهذا الموضوع .
http://vb4arab.com/vb/showthread.php?t=12294
2- LINQ TO XML :
درس آخر للاستاذ محمد سامر حول هذا الموضوع .
http://vb4arab.com/vb/showthread.php?t=9126
أما النوع الثالث فسنفرد له موضوعاً مستقلاً هو آخر مواضيعنا حول LINQ في الدرس القادم .
3- LINQ TO SQL :
فئة من فئات LINQ موجهة خصيصاً لدعم SQL Server ، في العادة هي الأكثر استخداما وسنحاول التعرف عليها سريعاً في هذا الدرس .
- البحث والاستعلام :
تعرفنا عليه سابقاً ، هذا المثال مثلاً لاعادة الاسم وتاريخ التخرج على شكل فئة جديدة للأشخاص الذين يزيد عمرهم عن 30 سنة ويقطنون في مصر :
var query = from c in Employee
where c.Age > 30
&&
c.Countery == "Egypt"
Select new { c.Name, c.GraduationDate};
- استدعاء Stored Procedures :
كل ما عليك هو فقط تعريف دالة تشابه Procedure لها نفس ال Attributes ، وهي ما يقوم بها الفيجوال ستوديو افتراضياً ، الآن كل ما عليك هو كتابة أمر بهذا الشكل ( استعلام يستقبل متغير واحد ) :
var c = db.ProceduresName("Egypt");
- Compiled Query :
إذا كان هناك جملة استعلام ستستخدمها لعدة مرات فليس من المنطقي جعل نظام قواعد البيانات يتعرف من جديد على الاستعلام كل مرة ، لذا توفر لنا نظم قواعد البيانات الحل لهذه النقطة ، أيضاً LINQ تقدم لنا ذات النظرية عبر ما يسمى باسم Compiled Query .
فكرة ال Compiled Query ببساطة تعتمد على استخدام دالة CompiledQuery.Compile لعمل Compile لجملة الاستعلام ، الشكل التالي كمثال :
var c = CompiledQuery.Compile(
( DataContext context, string counteryName, int age) =>
from c in Employee
where c.Age > age
&&
c.Countery == counteryName
select new { c.CustomerID, c.CompanyName, c.City } );
والآن يمكنك تجربة استخدامها لأكثر من مرة بتغيير البارميتر فقط ، والبحث في الاستعلام الذي تم عمل Compile له :
foreach ( var row in query(dc, "Egypt",22))
{
}
foreach ( var row in query(dc, "USA",28))
{
}
foreach ( var row in query(dc, "Saudi",38))
{
}
استخدام دوال في جملة الاستعلام :
لو فرضنا جملة الاستعلام التالية :
SELECT SUM( emp.salary ) AS TotalSalary FROM Employee emp Join Department dem ON emp.DepartmentID = dep.ID Group By dep.ID
نستطيع كتابتها بشكل LINQ بالشكل التالي :
var c =
from emp in db.Employee
join dep in db.Department
on emp.DepartmentID equals dep.ID
into TotalSalary
select TotalSalary.Sum( emp => emp.Salary );
استخدام جمل الاستعلام داخل LINQ :
قد تجد نفسك مضطراً احياناً لاستخدام واحدة من مميزات جمل الاستعلام التقليدية مثل الأمر PIVOT ، على كل هذه هي الصيغة العام لتنفيذ جملة SQL داخل ال LINQ :
- مثال منقول - :
var query = db.ExecuteQuery<EmployeeInfo>(@" With EmployeeHierarchy (EmployeeID, LastName, FirstName, ReportsTo, HierachyLevel) AS ( SELECT EmployeeID, LastName, ForstName, ReportsTo, 1 as HierarchyLevel FROM Employees WHERE ReportsTo IS NULL UNION ALL SELECT e.EmployeeID, e.LastName, e.FirstName, e.ReportsTo, eh.HierarchyLevel + 1 AS HierarchyLevel FROM Emplyees e INNER JOIN EmployeeHierarchy eh ON e.ReportsTo = eh.EmplyeeID ) SELECT * FROM EmployeeHierarchy ORDER BY HierarvhyLevel, LastName, FirstName" );
استخدام Inseret في LINQ:
var NewEmp = new Employee { [First Name] = "Ahmed", Age = 25, Countery="Egypt"};
db.Employee.Add( NewEmp );
في المثال السابق قمنا باضافة موظف جديد باسم أحمد وبعمر 25 سنة ومن مصر .
استخدام Update :
var EditEmp = db.Employee.Single
( c => c.Countery == "Egypt" );
EditEmp.Age = 30
في المثال السابق قمنا بالتعديل لعمر كل الاشخاص من مصر ليصبح 30 سنة .
استخدام Delete :
var deleteEmp = db.Employee.Single
( c => c.Age > 50 );
db.Employee.Remove( deleteEmp );
في المثال السابق قمنا بحذف الموظفين الذين تزيد اعمارهم عن 50 سنة .
SubmitChanges:
بعد اي عملية للاضافة أو للحذف أو التعديل لا بد من استدعاء الدالة db.SubmitChanges() لتفعيل التغييرات في قاعدة البيانات .
التحديث بالتزامن في قاعدة البيانات :
*** ال LINQ تتعامل بالوضع المنفصل وليس المتصل ، لذا ستجد له الكائن ChangeConflictExeption والذي ينتج عن تعارض عمليات التعديل على قاعدة البيانات بين عدة مستخدمين ، يمكن استعراض رسالة الخطأ بالشكل التالي :
try
{
Db2.SubmitChanges();
Break;
}
Catch ( ChangeConflictExeption ex)
{
MessageBox.Show( ex.Message );
Db2.*******( somequery, *******Mode.KeepChanges );
}
هنا يحاول الاستعلام التنفيذ ، لو لم يستطع يظهر رسالة الخطأ ويحاول مع أمر ******* مرة أخرى .
يمكن ايضاً في الأمر SubmitChanges تحديد سلوك البرنامج في حالة حدوث تعارض مثل الشكل التالي :
Db.SubmitChanges(ConflictMode.FailOnFirstConflict) ;
Db.SubmitChanges(ConflictMode.ContinueOnConflict);
وذلك من الفئة ConflictMode والتي لا تحتوي سوى على هذين العنصرين .
انشاء فئات LINQ TO SQL من خلال الفيجوال ستوديو :
يمكنك الفيجوال ستوديو 2008 من انشاء LINQ TO SQL Classes يمكنك التحكم بها لاحقاً ، من الشاشة الأولى :
http://vb4arab.com/vb/uploaded/3/01217411271.jpg
بعد اختياره ، يمكنك انشاء علاقات وجداول جديدة او سحب قاعدة بيانات من ال Server Explorer ، لذا قم بفتح قاعدة البيانات الخاصة بنا وقم بالبدء بسحب الجداول ، ستجد الشكل العام التالي :
http://vb4arab.com/vb/uploaded/3/11217411271.jpg
الآن بكل بساطة ستلاحظ ان الفيجوال ستوديو قام بمساعدتك في انشاء Data Access Layer - لو كنت تتذكرها - ، ستجد تعريفات للدوال التالية مثلاً :
partial void InsertEmployee_info(Employee_info instance);
partial void UpdateEmployee_info(Employee_info instance);
partial void DeleteEmployee_info(Employee_info instance);
الآن يمكنك كتابة كود كل منها لتسهيل الأمر لاحقاً على باقي مطورين الفريق ...
إلى هنا تكون دروسنا المتعلقة ب LINQ وما يتبعها من قواعد البيانات قد انتهت ، ربما نعود لقواعد البيانات بصورة مبسطة مرة اخرى مع دروس الويب .
والله الموفق ...
والسلام عليكم ورحمة الله وبركاته .