C# ADO.NET:بالقيم الخالية و DbNull — هل هناك أكثر كفاءة syntax ؟
سؤال
لدي DateTime?
أن أحاول أن أدخل في الحقل باستخدام DbParameter
.أنا خلق المعلمة مثل ذلك:
DbParameter datePrm = updateStmt.CreateParameter();
datePrm.ParameterName = "@change_date";
ثم أريد أن أضع قيمة DateTime?
في dataPrm.Value
في حين يمثل null
s.
ظننت في البداية أود أن تكون ذكية:
datePrm.Value = nullableDate ?? DBNull.Value;
ولكن فشلت مع الخطأ
المشغل '??' لا يمكن تطبيق المعاملات من النوع 'System.التاريخ والوقت ؟ " و " النظام.DBNull'
لذلك أعتقد أن هذا يعمل فقط إذا كان الثاني الحجة غير nullable إصدار أول حجة.ثم ذهبت:
datePrm.Value = nullableDate.HasValue ? nullableDate.Value : DBNull.Value;
ولكن هذا لا يعمل إما:
نوع من التعبير الشرطي لا يمكن تحديده لأنه لا يوجد التحويل الضمني بين 'System.DateTime' و 'النظام.DBNull'
ولكن أنا لا أريد تحويل بين تلك الأنواع!
حتى الآن الشيء الوحيد الذي يمكنني الحصول على العمل هو:
if (nullableDate.HasValue)
datePrm.Value = nullableDate.Value;
else
datePrm.Value = DBNull.Value;
هل هذه هي الطريقة الوحيدة التي يمكنني أن أكتب هذا ؟ هل هناك طريقة للحصول على بطانة واحدة باستخدام مشغل الثلاثي إلى العمل ؟
تحديث: أنا حقا لا أفهم لماذا ؟ ؟ النسخة لا تعمل.MSDN يقول:
؟ ؟ المشغل إرجاع اليسرى المعامل إذا لم يكن null, وإلا فإنه يعود حق المعامل.
هذا هو بالضبط ما أريد!
Update2: حسنا لقد كان جليا في النهاية:
datePrm.Value = nullableDate ?? (object)DBNull.Value;
المحلول
آه ها!لقد وجدت من حل أكثر كفاءة من @Trebz هو!
datePrm.Value = nullableDate ?? (object)DBNull.Value;
نصائح أخرى
إذا كنت تستخدم SQLServer ، System.Data.SqlTypes
مساحة يحتوي على بعض المرافق الفئات التي تجنب مزعج نوع الصب.على سبيل المثال بدلا من هذا:
var val = (object) "abc" ?? DBNull.Value;
يمكنك كتابة هذا:
var val = "abc" ?? SqlString.Null;
أنها سوف تعمل إذا كنت تستخدم
datePrm.Value = nullableDate.HasValue ? (object)nullableDate.Value : DBNull.Value;
إذا كنت تستخدم C# 3.0 يمكنك إنشاء امتداد طريقة للقيام بذلك سهلة:
public static class DBNullableExtensions
{
public static object ToDBValue<T>(this Nullable<T> value) where T:struct
{
return value.HasValue ? (object)value.Value : DBNull.Value;
}
}
class Program
{
static void Main(string[] args)
{
int? x = null;
Console.WriteLine( x.ToDBValue() == DBNull.Value );
}
}
أعتقد خطأ مع المحاولة الثانية يرجع إلى nullableDate.قيمة DBNull.القيمة أنواع مختلفة و مشغل الثلاثي تحتاج إلى اختيار نوع واحد من العودة في كل الحالات.ليس لدي البيئة لاختبار هذا ولكن أعتقد أن هذا يجب أن تعمل من أجلك:
datePrm.Value = nullableDate.HasValue ? (object)nullableDate.Value : (object)DBNull.Value;
الطريقة التي كنت تفعل ذلك ، يجب ثابت فئة فائدة أن يذهب فقط من خلال التحقق لمعرفة ما إذا كانت المعلمة القيمة null, ثم تعيين القيمة إلى القيام DBNull.أنا فقط تفعل ذلك قبل أن أتصل التنفيذ.