Frage

Der folgende Code gibt einen Fehler an: "Keine implizite Konvertierung von dbnull zu int."

SqlParameter[] parameters = new SqlParameter[1];    
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex;
parameters[0] = planIndexParameter;
War es hilfreich?

Lösung

Das Problem ist, dass die ?: Der Betreiber kann den Rückgabetyp nicht bestimmen, da Sie entweder eine zurückgeben int Wert oder ein dbnull -Typwert, der nicht kompatibel ist.

Sie können natürlich die Instanz von AgeIndex als Typ ausgeben object das würde das befriedigen ?: Erfordernis.

Du kannst den ... benutzen ?? Null-Koalescing-Operator wie folgt

SqlParameter[] parameters = new SqlParameter[1];     
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (object)AgeItem.AgeIndex ?? DBNull.Value;
parameters[0] = planIndexParameter; 

Hier ist ein Zitat von der MSDN -Dokumentation für die ?: Bediener, der das Problem erklärt

Entweder muss der Typ der First_expression und der zweite_expression der gleiche sein, oder eine implizite Konvertierung muss von einem Typ zum anderen vorhanden sein.

Andere Tipps

Die akzeptierte Antwort schlägt vor, eine Besetzung zu verwenden. Die meisten SQL -Typen haben jedoch ein spezielles Nullfeld, mit dem diese Besetzung vermieden werden kann.

Zum Beispiel, SqlInt32.Null "Repräsentiert einen dbnull, der dieser Instanz der SQLint32 -Klasse zugeordnet werden kann."

int? example = null;
object exampleCast = (object) example ?? DBNull.Value;
object exampleNoCast = example ?? SqlInt32.Null;

Sie brauchen Pass DBNull.Value Als NULL -Parameter innerhalb von SQLCommand, sofern ein Standardwert nicht in der gespeicherten Prozedur angegeben ist (wenn Sie gespeicherte Prozedur verwenden). Der beste Ansatz ist zuzuweisen DBNull.Value Für einen fehlenden Parameter vor der Abfrageausführung und nach Foreach wird der Job erledigt.

foreach (SqlParameter parameter in sqlCmd.Parameters)
{
    if (parameter.Value == null)
    {
        parameter.Value = DBNull.Value;
    }
}

Ansonsten ändern Sie diese Zeile:

planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex;

Folgendermaßen:

if (AgeItem.AgeIndex== null)
    planIndexParameter.Value = DBNull.Value;
else
    planIndexParameter.Value = AgeItem.AgeIndex;

Da Sie in der bedingten Anweisung nicht unterschiedliche Werte verwenden können, unterscheiden sich DBNULL und INT voneinander. Hoffe das wird helfen.

Versuchen Sie mit einer Codezeile Folgendes:

var piParameter = new SqlParameter("@AgeIndex", AgeItem.AgeIndex ?? (object)DBNull.Value);

Versuche dies:

SqlParameter[] parameters = new SqlParameter[1];    
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);

planIndexParameter.IsNullable = true; // Add this line

planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex== ;
parameters[0] = planIndexParameter;

Wenn Sie den bedingten (ternären) Operator verwenden, benötigt der Compiler eine implizite Konvertierung zwischen beiden Typen, andernfalls erhalten Sie eine Ausnahme.

Sie könnten es also reparieren, indem Sie eines von beidem anwenden System.Object:

planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : (object) AgeItem.AgeIndex;

Da das Ergebnis jedoch nicht wirklich hübsch ist und Sie sich immer an dieses Casting erinnern müssen, können Sie stattdessen eine solche Erweiterungsmethode verwenden:

public static object GetDBNullOrValue<T>(this T val)
{
    bool isDbNull = true;
    Type t = typeof(T);

    if (Nullable.GetUnderlyingType(t) != null)
        isDbNull = EqualityComparer<T>.Default.Equals(default(T), val);
    else if (t.IsValueType)
        isDbNull = false;
    else
        isDbNull = val == null;

    return isDbNull ? DBNull.Value : (object) val;
}

Dann können Sie diesen prägnanten Code verwenden:

planIndexParameter.Value = AgeItem.AgeIndex.GetDBNullOrValue();

Meiner Meinung nach ist es besser, dies mit dem zu tun Parameter Eigentum des SQLCommand Klasse:

public static void AddCommandParameter(SqlCommand myCommand)
{
    myCommand.Parameters.AddWithValue(
        "@AgeIndex",
        (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex);
}

Erwägen Sie, die verfügbare Nullable -Struktur (T) zu verwenden. Sie können nur Werte festlegen, wenn Sie sie haben, und Ihre SQL -Befehlsobjekte erkennen den nullablen Wert und verarbeiten entsprechend ohne Probleme an Ihrem Ende.

Versuche dies:

if (AgeItem.AgeIndex != null)
{
   SqlParameter[] parameters = new SqlParameter[1];
   SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
   planIndexParameter.Value = AgeItem.AgeIndex;
   parameters[0] = planIndexParameter;
}

Mit anderen Worten, wenn der Parameter null ist, senden Sie ihn einfach nicht an Ihren gespeicherten Proc (unter der Annahme, dass der gespeicherte Proc NULL -Parameter akzeptiert, was in Ihrer Frage impliziert ist).

Probieren Sie so etwas aus:

if (_id_categoria_padre > 0)
{
    objComando.Parameters.Add("id_categoria_padre", SqlDbType.Int).Value = _id_categoria_padre;
}
else
{
    objComando.Parameters.Add("id_categoria_padre", DBNull.Value).Value = DBNull.Value;
}
int? nullableValue = null;
object nullableValueDB
{
   get{
       if(nullableValue==null)
          return DBNull.Value;
       else
          return (int)nullableValue;
   }
}

Ich löste so.

if (_id_categoria_padre > 0)
{
    objComando.Parameters.Add("id_categoria_padre", SqlDbType.Int).Value = _id_categoria_padre;
}
else
{
    objComando.Parameters.Add("id_categoria_padre", DBNull.Value).Value = DBNull.Value;
}
if (AgeItem.AgeIndex== null)  
    cmd.Parameters.Add(new SqlParameter("ParaMeterName", SqlDbType.DateTime).Value = DBNull);  
else  
    cmd.Parameters.Add(new SqlParameter("ParaMeterName", SqlDbType.DateTime).Value = AgeItem.AgeIndex);

Das mache ich einfach ...

        var PhoneParam = new SqlParameter("@Phone", DBNull.Value);
        if (user.User_Info_Phone != null)
        {
            PhoneParam.SqlValue = user.User_Info_Phone;
        }

        return this.Database.SqlQuery<CustLogonDM>("UpdateUserInfo @UserName, @NameLast, @NameMiddle, @NameFirst, @Address, @City, @State, @PostalCode, @Phone",
            UserNameParam, NameLastParam, NameMiddleParam, NameFirstParam, AddressParam, CityParam, StateParam, PostalParam, PhoneParam).Single();
            dynamic psd = DBNull.Value;

            if (schedule.pushScheduleDate > DateTime.MinValue)
            {
                psd = schedule.pushScheduleDate;
            }


            sql.DBController.RunGeneralStoredProcedureNonQuery("SchedulePush",
                     new string[] { "@PushScheduleDate"},
                     new object[] { psd }, 10, "PushCenter");

Eine einfache Erweiterungsmethode dafür wäre:

    public static void AddParameter(this SqlCommand sqlCommand, string parameterName, 
        SqlDbType sqlDbType, object item)
    {
        sqlCommand.Parameters.Add(parameterName, sqlDbType).Value = item ?? DBNull.Value;
    }

Ich verwende eine einfache Methode mit einem Null -Check.

    public SqlParameter GetNullableParameter(string parameterName, object value)
    {
        if (value != null)
        {
            return new SqlParameter(parameterName, value);
        }
        else
        {
            return new SqlParameter(parameterName, DBNull.Value);
        }
    }

Mein Code, der in Real Project arbeitet, schauen Sie den ternären Operator beavor, der den SQLParameter macht. Dies ist der beste Weg für mich, mit Problemen:

    public bool Key_AddExisting
    (
          string clave
        , int? idHito_FileServer
        , int? idTipoDocumental_Almacen
        , string tipoExp_CHJ
        , int idTipoExp_Verti2
        , int idMov_Verti2
    )
    {
        List<SqlParameter> pars = new List<SqlParameter>()
        {
              new SqlParameter { ParameterName = "@Clave", Value = clave }
    LOOK -> , idHito_FileServer == null ? new SqlParameter { ParameterName = "@IdHito_FileServer", Value = DBNull.Value } : new SqlParameter { ParameterName = "@IdHito_FileServer", Value = idHito_FileServer }
    LOOK -> , idTipoDocumental_Almacen == null ? new SqlParameter { ParameterName = "@IdTipoDocumental_Almacen", Value = DBNull.Value } : new SqlParameter { ParameterName = "@IdTipoDocumental_Almacen", Value = idTipoDocumental_Almacen }
            , new SqlParameter { ParameterName = "@TipoExp_CHJ", Value = tipoExp_CHJ }
            , new SqlParameter { ParameterName = "@IdTipoExp_Verti2", Value = idTipoExp_Verti2 }
            , new SqlParameter { ParameterName = "@IdMov_Verti2", Value = idMov_Verti2 }
        };

        string sql = "INSERT INTO [dbo].[Enlaces_ClavesCHJ_MovimientosVerti2] " +
            "( " +
            "  [Clave] " +
            ", [IdHito_FileServer] " +
            ", [IdTipoDocumental_Almacen] " +
            ", [TipoExp_CHJ] " +
            ", [IdTipoExp_Verti2] " +
            ", [IdMov_Verti2] " +
            ") " +
            "VALUES" +
            "( " +
            "  @Clave" +
            ", @IdHito_FileServer" +
            ", @IdTipoDocumental_Almacen" +
            ", @TipoExp_CHJ" +
            ", @IdTipoExp_Verti2" +
            ", @IdMov_Verti2" +
            ")";

        return DbBasic.ExecNonQuery(ref this.conn, sql, pars);
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top