118 votes

Les données sont nulles. Cette méthode ou propriété ne peut pas être appelée sur des valeurs nulles.

Je travaille sur une application où l'on peut obtenir des informations sur des films à partir d'une base de données ainsi que ajouter, mettre à jour et supprimer les films. Dans la base de données, j'ai trois tables (Film, Genre et MovieGenre <- stocke les films et leur(s) genre(s)). Tout fonctionne bien sauf une chose, et c'est lorsque un film n'a pas de genres (ce qui devrait être possible).

Le problème se produit dans la méthode ci-dessous, et l'exception suivante est levée: Les données sont nulles. Cette méthode ou propriété ne peut pas être appelée sur des valeurs nulles.

La raison (bien sûr) est que la procédure stockée retourne null car le film n'a pas de genres, mais je n'arrive pas à comprendre comment éviter que cette exception soit levée. Comme je l'ai dit, il devrait être possible de stocker un film sans stocker aucune information sur son/ses genre(s).

La méthode:

public List GetMovieGenrebyMovieID(int movieID) {

    using (SqlConnection conn = CreateConnection()) {
        try {

            SqlCommand cmd = new SqlCommand("dbo.usp_GetMovieGenreByMovieID", conn);
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.AddWithValue("@MovieID", movieID);

            List movieGenre = new List(10);

            conn.Open();

            using (SqlDataReader reader = cmd.ExecuteReader()) {

                int movieGenreIDIndex = reader.GetOrdinal("MovieGenreID");
                int movieIDIndex = reader.GetOrdinal("MovieID");
                int genreIDIndex = reader.GetOrdinal("GenreID");

                while (reader.Read()) {

                    movieGenre.Add(new MovieGenre {
                        MovieID = reader.GetInt32(movieIDIndex),
                        MovieGenreID = reader.GetInt32(movieGenreIDIndex),
                        GenreID = reader.GetInt32(genreIDIndex)
                    });
                }
            }

            movieGenre.TrimExcess();

            return movieGenre;
        }
        catch {
            throw new ApplicationException();
        }
    }
}

La procédure stockée:

ALTER PROCEDURE usp_GetMovieGenreByMovieID
@MovieID int
AS
BEGIN
    BEGIN TRY
        SELECT m.MovieID, g.GenreID, mg.MovieGenreID, g.Genre
        FROM Movie AS m
        LEFT JOIN MovieGenre AS mg
            ON m.MovieId = mg.MovieID
        LEFT JOIN Genre AS g
            ON mg.GenreID = g.GenreID
        WHERE m.MovieID = @MovieID
    END TRY
    BEGIN CATCH
        RAISERROR ('Erreur lors de la tentative de récupération du/des genre(s)',16,1)
    END CATCH
END

4voto

mammadkoma Points 309

J'ai rencontré ce problème dans un projet .net5 data first, car un champ dans la base de données était nullable mais dans la classe d'entité c# était required. Après avoir recréé les entités avec l'extension de outils de puissance ef core, le problème a été résolu.

3voto

La réponse la plus simple est de remplacer les valeurs nulles par des valeurs non nulles. Essayez :

ALTER PROCEDURE usp_GetMovieGenreByMovieID
@MovieID int
AS
BEGIN
    BEGIN TRY
        SELECT m.MovieID, 
               COALESCE(g.GenreID,0) GenreID, 
               COALESCE(mg.MovieGenreID,0) MovieGenreID, 
               COALESCE(g.Genre, 'Non Applicable') Genre
        FROM Movie AS m
        LEFT JOIN MovieGenre AS mg
            ON m.MovieId = mg.MovieID
        LEFT JOIN Genre AS g
            ON mg.GenreID = g.GenreID
        WHERE m.MovieID = @MovieID
    END TRY
    BEGIN CATCH
        RAISERROR ('Erreur lors de la tentative de réception du(s) genre(s).',16,1)
    END CATCH
END

3voto

Si quelqu'un a rencontré ce problème, voici mon cas.

Je construis une API WEB. Avant d'ajouter l'attribut [Requis] - https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute?view=net-5.0, j'avais des valeurs NULL dans ma base de données. Ensuite, j'ai ajouté cet attribut à mon modèle et j'essayais de faire une requête GET, mais "System.InvalidOperationException: Les données sont NULL à l'ordinal 1. Cette méthode ne peut pas être appelée sur des valeurs NULL. Vérifiez en utilisant IsDBNull avant d'appeler." s'affichait.

J'ai donc supprimé les valeurs NULL des bases de données et toutes les requêtes ont fonctionné correctement par la suite. De ce que j'ai compris, une erreur se produit parce qu'EF Core ne permet pas de valeurs NULL dans la base de données lorsque l'attribut [Requis] est appliqué.

J'espère que cela sera utile pour quelqu'un.

1voto

Sajeeb Chandan Points 476

Aujourd'hui, j'ai rencontré ce problème. Mais le mien a été résolu d'une autre façon. Si un jour quelqu'un tombe dessus, la réponse est pour eux.

Comme il s'agit d'une exception générique C# .NET CLI

J'ai ajouté une nouvelle clé étrangère à l'une de mes tables de base de données sans valeur par défaut. Ainsi, la valeur a été définie sur NULL car cette colonne était autorisée à être nulle. Et j'ai reçu cette exception lors de l'interrogation de cette table.

Comme solution, j'ai remplacé les valeurs NULL par des valeurs appropriées (comme ce sont des clés étrangères, elles doivent être appropriées).

C'est tout.

Merci.

1voto

Kaloyan Drenski Points 162

Pour moi, cela s'est produit parce que dans la base de données j'avais une colonne 'XYZ' qui avait une valeur NULL, mais la propriété du modèle qui y était mappée (booléen) n'était pas nullable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X