شكرا أخي هاني على هذه المبادرات ... أنا أيضا كنت أحضر لكتابة الاضافات الجديده منذ زمن بعيد ولكن كنت أتكاسل كثيرا :D خصوصا بأن المنتدى لا يتفاعل بالشكل الذي يشجع.
لذلك ... بعد اذنك سأقوم بكتابة بعض الأشياء.
فأنا أود التحدث عن الـ <_< Nullable Types أولا ::
يمكننا أن نقوم في سي شارب 2 بكتابة كود بهذا الشكل ::
If ( myInteger == null )
{
//
}ولكن كل شئ لكنه قوانينه .. فالمتغير myInteger الذي قمت باختباره اذا كان null أم لا في الكود السابق لم أعلن عنه بالطريقه العاديه ولكن بطريقه جديده في سي شارب 2 ... قمت بالاعلان هكذا ::
Int? myInteger;
علامة الاستفهام الموجوده في الكود ليست خطأ مني ولكنها هى العلامه التي تستخدم عندما نريد الاعلان عن Value Type بأنه يمكن أن يسواي = null.
أو يمكن الاعلان عنه هكذا ::
Nullable<int> myInteger;
الأمر يشبه قليلا بشئ ما في قواعد البيانات .. فعندما نحدد الـ Date Type لاحدى الأعمده في جدول في قاعدة البيانات ... فاننا نقوم بتحديد مثلا نوعه int وبعد ذلك نخبر الجدول بأنه من الممكن أن لا تحتوي على شئ = Allow Nulls.
يمكننا التعامل مع هذه الأنواع من خلال الـ Properties مثل Value التي ترجع لنا القيمه التي يحتويها وأيضا من خلال HasValue التي ترجع لنا Boolean لتفيد لنا ما اذا كان المتغير يحتوي فعلا على قيمه أو لا يحتوي على شئ ( null ).
مثال ::
int? myInteger = null;
If(myInteger == null)
{
//
}
myInteger = 4;
int myInteger2 = myInteger.Value;
أو
int myInteger2 = (int)myInteger;
if (myInteger.HasValue)
{
//True
}ملحوظه :: الـ Value هى ReadOnly لذلك لا يمكنك كتابة ذلك ::
int? myInteger = 4; myInteger.Value = 56;
طبعا تلك الأمثله السابقه لا تعبر عن الغرض الذي تم من أجله اضافه الـ Nullable Types في سي شارب 2.
قرأت في الـ MSDN ووجدتهم هناك يقولون أنها من اجل التعامل مع قواعد البيانات ::
avariable of nullable type can represent all the values of its underlying type, plus an additional null value. This is particularly useful when dealing with databases and other data types containing elements that may not be assigned a value, or which may not exist
وفعلا هذا الأمر جيد جدا كما توقعت ... فلن ينبغي علينا في سي شارب 2 التأكد من البيانات التي ترجع من قواعد البيانات من أنها null !
وهذا أنا علمته منذ زمن ولكني لم أجرب التعامل مع قواعد البيانات والاستفاده من الـ Nullable Types معها قبل ذلك اطلاقا , ولكن وأنا أكتب هذا الموضوع كنت قد قررت أن أضيف مثالا لها ولكني فشلت فشل كبير ,
انظر مثلا الى هذا الجدول الذي قمت بانشائه في SQL Server باسم ATMembers ::
وقمت باضافة بعض البيانات ::
وبما أن الـ MSDN تقول أنه يمكننا استخدامها مع قواعد البيانات .. فبالتأكيد أنهم يقصدون كتابة الكود التالي باطمئنان في سي شارب 2 بدون اختبار اذا كانت القيمه تساوي DBNull أم لا ::
SqlCommand myCom = new SqlCommand("Select * from ATMembers", myCon);
SqlDataReader myReader = myCom.ExecuteReader();
int? theAge = null;
while (myReader.Read())
{
theAge = myReader.GetInt32(2);
//SomeMethod(theAge.Value,........
//.......
}ولكن للأسف يظهر لي NullValueException مباشرة عندما يجد أن قيمة احد الـ السن = null !!! مع ان المفروض أن المتغير theAge هو Nullable أصلا !!
معنى هذا وكأنه لم يتم اضافة شيئا جديدا فمازال يجب علينا اختبار اذا كان الـ age هو DBNull أم لا أولا كما نفعل في السي شارب الحاليه , أيضا قمت بتجربة استخدام Methods أخرى موجوده في الـDataReader وبعض المحاولات الأخرى ولكن بنفس النتيجه.
بعد ذلك قررت أن أجرب الاضافه الى الجدول فربما تكون الـ Nullable Types مدعومه هناك ولكن أيضا فشلت ::
قمت بعمل SP اسمها AddMember للاضافه ::
CREATE Proc AddMember @fname char(10),@lname char(10),@age int As insert ATMembers values(@fname,@lname,@age)
وبعد ذلك جربت الكود ::
SqlCommand myCom = new SqlCommand("AddMember", myCon);
myCom.CommandType = CommandType.StoredProcedure;
string firstName = "Hany";
string lastName = "Atasy";
Nullable<int> age = null;
myCom.Parameters.AddWithValue("@fname", firstName);
myCom.Parameters.AddWithValue("@lname", lastName);
myCom.Parameters.AddWithValue("@age", age );
int rowsAffected = myCom.ExecuteNonQuery();أيضا الكود لا يعمل ... طبعا هذا شئ غريب لا أفهمه حتى الآن .. ولكن من الواضح أن جميع الكلاسات المسؤوله عن التعامل مع قواعد البيانات لا تدعم الـ Nullable Types حتى الآن بالرغم من الـ MSDN يؤكدون فيه على أنها ميزه قويه عند التعامل مع قواعد البيانات ... فياريت لو يوجد من يعلم عن هذا الأمر .. يخبرنا به.
