10
votes

"Référence d'objet non définie à une instance d'un objet" - mais rien n'est nul?

Ouais, tu penses probablement; "Dieu, un autre?".

Oui, un autre. P>

"Référence d'objet non définie sur une instance d'un objet." P> blockQuote>

Je travaille avec EF6 récemment et après avoir développé pendant un certain temps, j'ai constaté qu'un peu plus d'optimisation était nécessaire. Beaucoup a été retravaillé sans problèmes, mais il semble que je ne puisse pas comprendre celui-ci. P>

dans ma candidature, j'utilise ce morceau de pseudo-code pour obtenir des articles de la base de données. P>

at MySql.Data.Entity.SqlGenerator.Visit(DbPropertyExpression expression)
at MySql.Data.Entity.SqlGenerator.Visit(DbInExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbInExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SqlGenerator.VisitBinaryExpression(DbExpression left, DbExpression right, String op)
at MySql.Data.Entity.SqlGenerator.Visit(DbAndExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbAndExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SelectGenerator.Visit(DbFilterExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbFilterExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SqlGenerator.VisitInputExpression(DbExpression e, String name, TypeUsage type)
at MySql.Data.Entity.SelectGenerator.VisitInputExpressionEnsureSelect(DbExpression e, String name, TypeUsage type)
at MySql.Data.Entity.SelectGenerator.Visit(DbProjectExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SelectGenerator.GenerateSQL(DbCommandTree tree)
at MySql.Data.MySqlClient.MySqlProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree)
at System.Data.Entity.Core.Common.DbProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)
at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateCommandDefinition(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver)
at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Boolean streaming, Span span, IEnumerable`1 compiledQueryParameters, AliasGenerator aliasGenerator)
at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__6()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at MyNameSpace.DbContextWrapper.<GetExistingNames>d__1b.MoveNext() in c:~omitted~\DbContextWrapper.cs:line 70
at MyNameSpace.NameProcessor.ProcessNames(List<string> inputNames) in c:~omitted~\NameProcessor.cs:line 60


19 commentaires

L'élément n'est peut-être pas nul, mais le foreach construit un itérateur autour d'elle. Fondamentalement, plus de code est en panne dans l'arrière-plan que vous ne comprenez pas, et ce code est quelle que soit la mise en œuvre de requête ( iquéryable ) est - ce qui est le Ef trucs.


@AdamHouldsworthorth je reçois le point où le foreach essaie de créer un itérateur et appeler movenext () , qui est sujet à la nullref si requête est null - mais il passe le si !


Est-ce que noms contient une référence? Êtes-vous sûr que contexte contient une référence? Est-ce que l'un des éléments de noms null peut-être? Et note que juste dire "oui, je sais, nullregreeneException, c'est différent mais" ne le rend pas différent. Toutes les questions autour de cela sont différentes, mais la solution est toujours la même, débogage, débogage, débogage. Je ne vois rien de nouveau ici.


@ Lassev.karlsen noms n'est définitivement pas null, ni n'est ni contexte . Bien sûr, j'ai débogué avant de poster ici. J'ajouterai cela à la question.


Pouvez-vous montrer le code appelant la fonction? Et où vient contexte ? Pouvez-vous montrer le code complet ici? Puisque vous utilisez ienumerable En conséquence, pouvez-vous afficher la boucle à l'aide du code à l'aide du code de disposition du code ?


Essayez Ajouter ienumerator test = requête.getenumerator (); et vérifier test . Est-ce nul?


Pour être clair Query ne sera jamais null, même si votre clause où la clause ne retournerait aucun enregistrement. Il est difficile de dire ce qu'est exactement NULL, mais pourquoi ne changez-vous pas la méthode complète vers le contexte de retour (n => noms.contains (n)). Sélectionnez (x => x.name)


@ReniUz the énumérateur est réellement créé, mais ce n'est pas null. Le courant est NULL, cependant. On vérifie que actuel résout mon problème ou est-ce plus une solution de contournement?


Comment peut-il être null ? est iquéryable , c'est context.names retourner une collection contenant un null référence? Cela semble étrange.


@ Lassev.karlsen après avoir appelé quelque chose dessus, oui. La seule chose qui s'appelle appelée est getenumerator () atm.


Non, ne vérifiez pas le courant. Pouvez-vous publier une cheminée complète?


@DIONV. Test Query pour NULL ne teste que la porte de la porte à beaucoup de code derrière elle. La création de l'itérateur déverrouille le code qui le pouvait le pouvant. Un foreach est excellent de cacher beaucoup de code, c'est là que la référence nulle provient de.


@DIONV. Si Current Propriété de l'énumérateur est NULL à un moment donné, vous n'êtes pas étonnant que vous obtenez NullReferenceException - Le contient méthode tente d'obtenir la valeur du Nom Propriété de l'objet inexistant (le prédicat est en fait évalué dans la méthode MOVENNEXT () de l'énumérateur). Un simple contexte.names.oftype () filtrera ces références nulles. Question intéressante Cependant, c'est pourquoi y a-t-il des nuls dans la collection ...


@DIONV. Sauf si vous parlez de actuel étant NULL avant le premier appel à MOVENEXT () - Dans ce cas, il est attendu.


@ Grx70, oui, il est null avant d'entrer foreach et appelant ainsi movenext .


Alors, que diriez-vous de StackTrace?


@Reniuz Je suis désolé, lisez-la, mais je doute que cela vous aiderait. Vous pouvez voir d'où il est appelé dans la partie éditée de ma question.


Eh bien, peut-être que cela montrera où plus profondément dans le code (que @AdamHouldsworth a parlé de) une erreur est survenue.


Lancer la crainte NullReferenceException Il n'y a rien de craint à ce sujet. C'est un problème commun avec une solution commune: trouvez ce qui est null puis assurez-vous qu'il soit initialisé avant d'appeler des méthodes dessus. Le code qui jette la nullreferenceException peut ne pas être dans votre propre code, mais cela peut être causé par quelque chose que vous faites dans votre code. Trouvez le code (même le code qui n'est pas à vous) et déterminez ce qui est null.


3 Réponses :


0
votes

Votre chèque NULL sur la requête ne manquera jamais, car il renvoie l'objet iqueriser (c'est-à-dire la requête en cours de construction). Vous l'avez instancié et a commencé à construire une requête, de sorte qu'il passera toujours.

Pour être clair - Iquéryable est à peu près équivalente à une chaîne contenant l'instruction ADO.NET SELECT. Ce n'est pas, par nature, les données réelles. P>

Cela n'explique pas pourquoi il lance une exception nulle, mais il em> explique pourquoi le chèque null passe, et le forach toujours échouer. p>

Edit: Lorsque vous essayez de la dupliquer, j'ai trouvé que je reçois une exception lors de l'utilisation du code ci-dessous: P>

IQueryable<Names> query = Names.Where(n => names.ToList().Contains(n.Name));


7 commentaires

Enumérant un iQueryable <> va en effet frapper la base de données. Et tandis que iquéryable <> est la recette pour savoir comment obtenir les données , enumérant sur celui-ci et produisant ainsi un objet ienumerator <> va chercher les données.


Je n'étais pas sûr si la requête est exécutée si j'essaie d'y accéder avec cette approche. Par conséquent, j'ai essayé de créer une liste de la requête en utilisant Tolist (), mais cela jette la même exception lors de la création de la liste - l'appel de Tolist () entraînera un NullReferenceException , malheureusement.


@ Lassev.Karlsen Fair Point - J'allais à la mémoire auparavant, j'ai supprimé cette partie de ma réponse.


Il répond effectivement pourquoi est-ce que cela passe le test, mais n'est-ce pas accessible? , je l'ai donc évité. Cela ne résout toutefois pas mon problème et je ne peux donc pas la marquer comme répondu.


@DIONV. Je suis un peu soupliée sur cela, bien que j'ai trouvé une exception différente lors de l'utilisation de l'ICollection. Mise à jour de ma réponse.


@Obsidianphoenix J'ai vu ça, et j'ai essayé de la même chose, mais je lance toujours la même erreur. Je pense que noms était déjà une liste car je passe dans la méthode ci-dessus (que vous pouvez voir dans la modification de mon message). Toujours coincé sur la même erreur si ...


@DIONV. Cela ressemble à une question de données potentielle alors, je suis soulevé à moins que vous puissiez vous réunir une reprophérose autonome que nous pouvons utiliser pour le faire lancer de notre côté. Nous aurions probablement besoin d'un exemple de la structure de la table complète et des échantillons de données, etc., espérons-le, quelqu'un de mieux que je ne verrai votre problème sans cela.



4
votes

Après avoir posté StackTrace, je vous ai repéré que vous utilisiez MySQL et que je suppose que vous avez frappé ce bogue: Exception lors de l'utilisation d'ienumera.contains (modèle.Property) dans l'endroit où prédicat

La solution serait donc de vous assurer que vous avez des versions de MySQL Connector / Net 6.7.6 / 6.8.4 / 6.9.5 et plus récente. Ou essayez d'utiliser toute méthode au lieu de contient .

P.s. Ce rapport de bogue est venu de cet article par Alnedru: int []. Contient non 'T Travailler dans EF6


5 commentaires

C'est en fait un gentil, je ne l'ai pas trouvé. J'utilise le connecteur / net 6.9.3, donc je suppose que cela ne contient pas ce bugfix?


Si je comprends bien, vous devez le mettre à jour au moins 6.9.5 pour obtenir le correctif.


A la façon dont j'ai cherché les premières entrées de la trace de pile et est venu à la question de la question que j'ai ajoutée à ma réponse. Afin que vous puissiez voir la trace de pile aide;)


J'étais absent du travail hier, mais je l'ai testé tout de suite ce matin et la mise à niveau a travaillé comme un charme. Merci beaucoup!


Bien d'entendre ça! Bonne chance.



-2
votes

Pourquoi ne pas simplement ajouter une méthode d'extension pour alléger le stress que cela vous amène. Essayez cette pièce de code xxx

puis appelez-la comme si xxx


1 commentaires

1) Cette question est déjà répondu il y a longtemps et 2) Vous ne pouvez pas simplement créer une extension pour chaîne et attendre l'entitéFramework pour créer une requête hors de celle-ci. Avez-vous essayé d'exécuter ce code par vous-même? Ce n'est pas parce qu'il compile que cela fonctionne. 3) Le problème n'était pas la chaîne nul, mais l'objet requête .