web-dev-qa-db-fra.com

Impossible de convertir implicitement le type 'int?' à 'int'.

Je reçois le message d'erreur "Impossible de convertir implicitement le type 'int?' Une conversion explicite existe (vous manque-t-il un cast?) "sur CommandSerHour à la ligne de retour. Je ne sais pas pourquoi parce que mes compétences en C # ne sont pas aussi avancées. Toute aide serait appréciée.

static int OrdersPerHour(string User)
{
    int? OrdersPerHour;
    OleDbConnection conn = new OleDbConnection(strAccessConn);
    DateTime curTime = DateTime.Now;        

    try
    {
        string query = "SELECT COUNT(ControlNumber) FROM Log WHERE DateChanged > #" + curTime.AddHours(-1) + "# AND User = '" + User + "' AND Log.EndStatus in ('Needs Review', 'Check Search', 'Vision Delivery', 'CA Review', '1TSI To Be Delivered');";
        OleDbCommand dbcommand = new OleDbCommand(query, conn);
        dbcommand.Connection.Open();
        dbcommand.CommandType = CommandType.Text;
        OrdersPerHour = (int?)dbcommand.ExecuteScalar();

        Console.WriteLine("Orders per hour for " + User + " is " + OrdersPerHour);            
    }
    catch (OleDbException ex)
    {

    }
    finally
    {
        conn.Close();
    }
    return OrdersPerHour;
}
16
MaylorTaylor

Eh bien, vous transcrivez OrdersPerHour en int?

OrdersPerHour = (int?)dbcommand.ExecuteScalar();

Pourtant, votre signature de méthode est int:

static int OrdersPerHour(string User)

Également une suggestion rapide -> Utilisez les paramètres de votre requête , quelque chose comme:

string query = "SELECT COUNT(ControlNumber) FROM Log WHERE DateChanged > ? AND User = ? AND Log.EndStatus in ('Needs Review', 'Check Search', 'Vision Delivery', 'CA Review', '1TSI To Be Delivered')";
OleDbCommand dbcommand = new OleDbCommand(query, conn);
dbcommand.Parameters.Add(curTime.AddHours(-1));
dbcommand.Parameters.Add(User);
13
Dimitar Dimitrov

c'est parce que le type de retour de votre méthode est int et OrdersPerHour est int? (nullable), vous pouvez résoudre ce problème en retournant sa valeur comme ci-dessous:

return OrdersPerHour.Value

vérifiez également si ce n'est pas null pour éviter une exception comme ci-dessous:

if(OrdersPerHour != null)
{

    return OrdersPerHour.Value;

}
else
{

  return 0; // depends on your choice

}

mais dans ce cas, vous devrez retourner une autre valeur dans la partie else ou après la partie if sinon le compilateur signalera une erreur indiquant que tous les chemins de code ne retournent pas.

11
tariq
Int32 OrdersPerHour = 0;
OrdersPerHour = Convert.ToInt32(dbcommand.ExecuteScalar());
6
FalloutBoy

Vous pouvez modifier la dernière ligne comme suit (en supposant que vous vouliez renvoyer 0 lorsqu'il n'y a rien dans db):

return OrdersPerHour == null ? 0 : OrdersPerHour.Value;
1
loopedcode

Le premier problème rencontré avec votre code est le message 

La variable locale OrdersPerHour peut ne pas être initialisée avant l'accès.

Cela se produit parce que dans le cas où votre requête de base de données déclencherait une exception, la valeur pourrait ne pas être définie sur quelque chose (vous avez une clause catch vide).

Pour résoudre ce problème, définissez la valeur sur ce que vous souhaitez si la requête échoue, à savoir probablement 0

int? OrdersPerHour = 0;

Une fois que cela est corrigé, il y a maintenant l'erreur sur laquelle vous écrivez. Cela est dû au fait que votre signature de méthode déclare que vous retournez une variable int, mais que vous retournez en fait une variable nullable int, int?,.

Donc, pour obtenir la partie int de votre int?, vous pouvez utiliser la propriété .Value

return OrdersPerHour.Value;

Toutefois, si vous avez déclaré que OrdersPerHour était null au début au lieu de 0, la valeur peut être null et une validation appropriée avant le renvoi est probablement nécessaire (générons une exception plus spécifique, par exemple).

Pour ce faire, vous pouvez utiliser la propriété HasValue pour vous assurer d'avoir une valeur avant de la renvoyer:

if (OrdersPerHour.HasValue){
    return OrdersPerHour.Value;
}
else{
    // Handle the case here
}

En passant, comme vous codez en C #, il serait préférable de suivre les conventions de C #. Votre paramètre et vos variables doivent être dans camelCase et non pas PascalCase. Donc User et OrdersPerHour seraient user et ordersPerHour.

1

Si vous êtes préoccupé par la valeur de retour null possible, vous pouvez également exécuter quelque chose comme ceci:

int ordersPerHour;  // can't be int? as it's different from method signature
// ... do stuff ... //
ordersPerHour = (dbcommand.ExecuteScalar() as int?).GetValueOrDefault();

De cette façon, vous traiterez les résultats potentiels inattendus et pourrez également fournir une valeur par défaut à l'expression en entrant .GetValueOrDefault(-1) ou quelque chose de plus significatif pour vous.

1
Rubens Farias

OrdersPerHour = (int?)dbcommand.ExecuteScalar();

Cette instruction doit être tapée comme suit, OrdersPerHour = (int)dbcommand.ExecuteScalar();

1
Josh

simple

(i == null) ? i.Value : 0;
0
HoQuocThinh

Le type de retour de votre méthode est int et vous essayez de renvoyer un int?.

0
cassiorgr