SqlParameter مع قيمة Nullable وإعطاء خطأ أثناء ExecuteNonQuery؟

StackOverflow https://stackoverflow.com/questions/863374

  •  21-08-2019
  •  | 
  •  

سؤال

ولدي استعلام SQL يحتوي على المعلمة التي يمكن أن تكون لاغية في قاعدة البيانات (مزود الخدمة). وتعمل بشكل جيد طريقة التحديث حتى أن المستخدم وضع فارغة في الميدان، هذا ينتج قيمة فارغة للكائن DataTime (هذا الكائن قيم الفارغة). المشكلة هي عندما dbCommand.ExecuteNonQuery();.

وهنا هو كيف أبني المعلمة لهذا الحقل:

    IDataParameter dbParam_au_id = new SqlParameter();
    dbParam_au_id.ParameterName = "@birthday";
    dbParam_au_id.Value = birthday;
    dbParam_au_id.DbType = DbType.DateTime;
    dbCommand.Parameters.Add(dbParam_au_id);

ولدي محاولة لتحويل قيمة خالية من عيد ميلاد لDBNull.Value مثل ما يلي:

    IDataParameter dbParam_au_id = new SqlParameter();
    dbParam_au_id.ParameterName = "@birthday";
    dbParam_au_id.Value = birthday??DBNull.Value;
    dbParam_au_id.DbType = DbType.DateTime;
    dbCommand.Parameters.Add(dbParam_au_id);

ولكن هل هذا الرمز لا ترجمة وأحصل على خطأ:

<اقتباس فقرة>   

والخطأ 1 المشغل '؟؟' لا يمكن تطبيقها على المعاملات من نوع 'System.DateTime؟ و'System.DBNull'

وأي فكرة؟

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

المحلول

وأنواع غير متوافقة. جرب شيئا من هذا القبيل:

dbParam_au_id.Value = (object)birthday ?? DBNull.Value;

نصائح أخرى

إذا كانت مكتوبة الطبقة SqlParameter بشكل صحيح في المرة الأولى ... سوف يتم التعامل معها على قيمة خالية C # كما DBNull.Value. ومن شأن ذلك أن تكون بديهية، وذلك بطبيعة الحال تحديد قيمة SqlParameter لاغية ما يعادل وظيفيا إلى إزالته من SqlParameterCollection.

لتصحيح هذا الخطأ تصميم API مثير للسخرية، وخلق أسلوب خاص بك AddParameter (مع الزائدة)، والتي تأخذ SqlParameterCollection، سلسلة (اسم المعلمة)، وكائن (قيمة المعلمة).

#region Add by Name/Value.
/// <summary>
/// Adds an input parameter with a name and value.  Automatically handles conversion of null object values to DBNull.Value.
/// </summary>
/// <param name="parameters">SqlParameterCollection from an SqlCommand instance.</param>
/// <param name="name">The name of the parameter to add.</param>
/// <param name="value">The value of the parameter to add.</param>
private static void AddParameter( SqlParameterCollection parameters, string name, object value )
{
    parameters.Add( new SqlParameter( name, value ?? DBNull.Value ) );
}

/// <summary>
/// Adds a parameter with a name and value.  You specify the input/output direction.  Automatically handles conversion of null object values to DBNull.Value.
/// </summary>
/// <param name="parameters">SqlParameterCollection from an SqlCommand instance.</param>
/// <param name="name">The name of the parameter to add.</param>
/// <param name="value">The value of the parameter to add.  If null, this is automatically converted to DBNull.Value.</param>
/// <param name="direction">The ParameterDirection of the parameter to add (input, output, input/output, or return value).</param>
private static void AddParameter( SqlParameterCollection parameters, string name, object value, ParameterDirection direction )
{
    SqlParameter parameter = new SqlParameter( name, value ?? DBNull.Value );
    parameter.Direction = direction;
    parameters.Add( parameter );
}
#endregion

#region Add by Name, Type, and Value.
/// <summary>
/// Adds an input parameter with a name, type, and value.  Automatically handles conversion of null object values to DBNull.Value.
/// </summary>
/// <param name="parameters">SqlParameterCollection from an SqlCommand instance.</param>
/// <param name="name">The name of the parameter to add.</param>
/// <param name="type">Specifies the SqlDbType of the parameter.</param>
/// <param name="value">The value of the parameter to add.  If null, this is automatically converted to DBNull.Value.</param>
private static void AddParameter( SqlParameterCollection parameters, string name, SqlDbType type, object value )
{
    AddParameter( parameters, name, type, 0, value ?? DBNull.Value, ParameterDirection.Input );
}

/// <summary>
/// Adds a parameter with a name, type, and value.  You specify the input/output direction.  Automatically handles conversion of null object values to DBNull.Value.
/// </summary>
/// <param name="parameters">SqlParameterCollection from an SqlCommand instance.</param>
/// <param name="name">The name of the parameter to add.</param>
/// <param name="type">Specifies the SqlDbType of the parameter.</param>
/// <param name="value">The value of the parameter to add.  If null, this is automatically converted to DBNull.Value.</param>
/// <param name="direction">The ParameterDirection of the parameter to add (input, output, input/output, or return value).</param>
private static void AddParameter( SqlParameterCollection parameters, string name, SqlDbType type, object value, ParameterDirection direction )
{
    AddParameter( parameters, name, type, 0, value ?? DBNull.Value, direction );
}
#endregion

#region Add by Name, Type, Size, and Value.
/// <summary>
/// Adds an input parameter with a name, type, size, and value.  Automatically handles conversion of null object values to DBNull.Value.
/// </summary>
/// <param name="parameters">SqlParameterCollection from an SqlCommand instance.</param>
/// <param name="name">The name of the parameter to add.</param>
/// <param name="type">Specifies the SqlDbType of the parameter.</param>
/// <param name="size">Specifies the size of the parameter for parameter types of variable size.  Set to zero to use the default size.</param>
/// <param name="value">The value of the parameter to add.  If null, this is automatically converted to DBNull.Value.</param>
private static void AddParameter( SqlParameterCollection parameters, string name, SqlDbType type, int size, object value )
{
    AddParameter( parameters, name, type, size, value ?? DBNull.Value, ParameterDirection.Input );
}

/// <summary>
/// Adds a parameter with a name, type, size, and value.  You specify the input/output direction.  Automatically handles conversion of null object values to DBNull.Value.
/// </summary>
/// <param name="parameters">SqlParameterCollection from an SqlCommand instance.</param>
/// <param name="name">The name of the parameter to add.</param>
/// <param name="type">Specifies the SqlDbType of the parameter.</param>
/// <param name="size">Specifies the size of the parameter for parameter types of variable size.  Set to zero to use the default size.</param>
/// <param name="value">The value of the parameter to add.  If null, this is automatically converted to DBNull.Value.</param>
/// <param name="direction">The ParameterDirection of the parameter to add (input, output, input/output, or return value).</param>
private static void AddParameter( SqlParameterCollection parameters, string name, SqlDbType type, int size, object value, ParameterDirection direction )
{
    SqlParameter parameter;
    if (size < 1)
        parameter = new SqlParameter( name, type );
    else
        parameter = new SqlParameter( name, type, size );
    parameter.Value = value ?? DBNull.Value;
    parameter.Direction = direction;
    parameters.Add( parameter );
}
#endregion

وكما ترون، داخل تلك الطريقة (والزائدة)، حيث يتم كتابتها قيمة بالفعل ككائن، وأنا استخدم "قيمة ؟؟ DBNull.Value" بيان لفرض باطل حكم = DBNull.Value.

والآن، عند تمرير مراجع الكائنات فارغة أو أنواع nullable مع أية قيم لطريقة AddParameter الخاص بك، فإنك تحصل على المتوقع، والسلوك بديهية، حيث يتم تمرير DBNull.Value إلى الاستعلام.

لا أستطيع أن أتخيل لماذا تم تنفيذ API كما هو، لأنه إذا أردت المعلمة لا يمكن تجاهله، وأنا لن إضافته ثم SET انها قيمة فارغة. I إما NOT إضافته في المقام الأول، أو أود أن إزالته من SqlParameterCollection. لو كنت ضيف معلمة، وSET انها قيمة (حتى إذا تم تعيين فارغة)، وأتوقع أن تكون المستخدمة في الاستعلام، وأتوقع فارغة إلى يعني قيمة فارغة.

ولقد سمعت أنها لم تنفذ عليه اسم "الصحيحة" وسيلة لأسباب تتعلق بالأداء، ولكن هذا أمر مثير للسخرية، كما يتبين، لأن الدعوة طريقة SqlParameterCollection.AddWithValue يحول كل شيء إلى كائن على أي حال، وتحويل مثيل قيم الفارغة بلا قيمة لاغية وجوه هو جزء لا يتجزأ من لغة C # وهي ليست الأداء ضرب على الإطلاق. ينبغي أن مايكروسوفت إصلاح حقا هذا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top