سؤال

أنا أكتب C# روتين الاتصال المخزنة proc.في قائمة المعلمات أنا يمر في ، فمن الممكن أن واحدة من القيم يمكن قانونا تكون فارغة.لذا فكرت في استخدام مثل هذا الخط:

cmd.Parameters.Add(new SqlParameter("@theParam", theParam ?? DBNull.Value));

للأسف هذا بإرجاع الخطأ التالي:

CS0019:المشغل '??' لا يمكن تطبيق المعاملات من نوع 'سلسلة' و 'النظام.DBNull'

الآن هذا يبدو واضحا بما فيه الكفاية, ولكن أنا لا أفهم المنطق وراء ذلك.لماذا هذا العمل ؟ (و في كثير من الأحيان عندما لا أفهم لماذا لا يعمل شيئا, ليس هذا لا يمكن العمل...أنا أفعل ذلك الخطأ.)

هل أنا حقا يجب أن تمتد هذه إلى أطول ثم إذا كان البيان ؟

تحرير: (بوصفها جانبا ، والذين يقولون أن مجرد استخدام "null" كما هي أنها لا تعمل.أنا أصلا فكرت فارغة وسوف لصناعة السيارات في ترجمة DBNull أيضا ، ولكن على ما يبدو لا.(من يدري؟))

هل كانت مفيدة؟

المحلول

ليس هكذا, لا.أنواع مباراة.نفس الشيء صحيح بالنسبة الثلاثي.

الآن, من خلال "مباراة", لا يعني أنها يجب أن تكون هي نفسها.لكنها لا يجب أن تكون مهمة متوافق.في الأساس:في نفس الميراث شجرة.

طريقة واحدة للحصول على جميع أنحاء هذا هو أن يلقي سلسلة الخاص بك على وجوه:

var result = (object)stringVar ?? DBNull.Value;

ولكن أنا لا أحب هذا, لأن ذلك يعني أنك تعتمد أكثر على SqlParameter منشئ للحصول على أنواع الحق.بدلا من ذلك, أود أن تفعل ذلك من هذا القبيل:

cmd.Parameters.Add("@theParam", SqlDbTypes.VarChar, 50).Value = theParam;
// ... assign other parameters as well, don't worry about nulls yet

// all parameters assigned: check for any nulls
foreach (var p in cmd.Parameters) 
{ 
    if (p.Value == null) p.Value = DBNull.Value; 
}

نلاحظ أيضا أن لا أعلن صراحة نوع المعلمة.

نصائح أخرى

new SqlParameter("@theParam", (object)theParam ?? DBNull.Value)

؟ ؟ المشغل إرجاع اليسرى المعامل إذا لم يكن null, وإلا فإنه يعود حق المعامل.ولكن في حالة أن تكون من أنواع مختلفة ، لذلك فإنه لا يعمل.

فارغة تتجمع المشغل فقط مع البيانات من نفس النوع.لا يمكنك إرسال فارغة إلى SqlParamater وهذا سيجعل Sql Server تقول أنك لم تحدد المعلمة.

يمكنك استخدام

new SqlParameter("@theParam", (object)theParam ?? (object)DBNull.Value)

أو يمكنك إنشاء دالة العودة DBNull عندما null وجدت مثل

public static object GetDataValue(object o)
{
    if (o == null || String.Empty.Equals(o))
        return DBNull.Value;
    else
        return o;
}

ثم اتصل

new SqlParameter("@theParam", GetDataValue(theParam))

السبب لا يمكنك استخدام null تتجمع المشغل هو أن لديها للعودة نوع واحد وأنت تقديم أكثر من نوع واحد. theParam هو سلسلة. DbNull.Value هو إشارة إلى ثابت سبيل المثال من نوع النظام.DbNull.هذا ما تنفيذها تبدو مثل ؛

public static readonly DBNull Value = new DBNull(); 
//the instantiation is actually in the 
//static constructor but that isn't important for this example

حتى إذا كنت تريد أن يكون NullCoalesce طريقة, ما من شأنه أن عودتها نوع تكون ؟ لا يمكن أن يكون كل نظام.سلسلة النظام.DbNull ، فإنه يجب أن تكون واحدة أو أخرى ، أو الأصل مشتركة نوع.

بحيث يؤدي إلى هذا النوع من المدونة ؛

cmd.Parameters.Add(
    new SqlParameter("@theParam", (object)theParam ?? (object)DBNull.Value)
);

في proc المخزنة عند اعلان واردة متغير ، يكون ذلك تعيين فار يساوي null ثم لا تمر عليه من csharp رمز ، ومن ثم التقاط القيمة الافتراضية من sql

@theParam as varchar(50) = null

ثم في csharp

if (theParam != null)
    cmd.Parameters.Add(new SqlParameter("@theParam", theParam));

هذا هو كيف لي أن عادة ما تمر الخيار و/أو تخلف القيم إلى تخزين procs

أنا متأكد من أن مجرد مرور فارغة إلى SqlParameter منشئ النتائج في إرسالها كما DBNull.القيمة...قد أكون مخطئا ، منذ يمكنني استخدام EnterpriseLibraries DB الوصول, ولكن أنا متأكد من أن إرسال رسالة فارغة على ما يرام هناك.

cmd.المعلمات.Add(new SqlParameter("@theParam", (theParam == null) ?DBNull.القيمة :theParam));

استخدام بناء الجملة التالي:

(theParam وجوه) ??(DBNull.قيمة كائن)

في هذه الحالة كلا أجزاء من المشغل ??هي من نفس النوع.

غير متأكد محددة الإجابة على سؤالك, ولكن ماذا عن هذا ؟

string.IsNullOrEmpty(theParam) ? DBNull.Value : theParam

أو إذا كان فارغا غير موافق

(theParam == null) ? DBNull.Value : theParam
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top