2017-08-12 3 views
0

J'utilise Visual Studio 2012 avec MySQL 5.7 Community Edition. J'obtiens la référence d'objet non définie à une instance d'objet sur la requête ci-dessous.Cadre d'entité MySQL avec requête corrigée par LinQ n'exécutant pas

var oList = (
    from dm in dbContext.document_master 
    join um in dbContext.user_master on dm.Alocated_CAA equals um.UserId 
    where (dm.DocumentHandle != null) 
    select new TaskLogReport 
    { 
     documentDate = dm.Document_Date, 
     documentHandle = dm.DocumentHandle, 
     fileNumber = dm.FileNumber, 
     statusRemarks = dbContext.statushistories 
      .Where(x => x.DocumentHandle == 12345678).FirstOrDefault().Remarks 
    }).ToList(); 

Dans la requête ci-dessus si je reçois le changement 12.345.678 à dm.DocumentHandle, puis faire référence d'objet non définie à une instance d'objet. Essayez avec le serveur MS-SQL, fonctionne correctement.

Répondre

1

Vous obtenez l'erreur car FirstOrDefault() renvoie null, car il n'y a aucun objet dont DocumentHandle est égal à dm.DocumentHandle. Changer dm.DocumentHandle à 12345678 fonctionne parce qu'il y a un élément correspondant.

Cette ligne est le problème:

.Where(x => x.DocumentHandle == 12345678).FirstOrDefault().Remarks 

C# »renvoie la méthode de Enumerable.FirstOrDefault() soit le premier élément de mise en correspondance d'une dénombrable, ou, s'il n'y en a pas, la valeur par défaut du type. Dans le cas de types nullables, FirstOrDefault() renvoie null si aucun élément n'est trouvé.

La raison pour laquelle vous n'obtenez aucune erreur lorsque vous utilisez 12345678 est qu'il existe au moins une valeur correspondante avec DocumentHandle. Toutefois, lorsque vous modifiez cela à dm.DocumentHandle, aucun élément correspondant n'est trouvé, entraînant FirstOrDefault pour renvoyer null. Ensuite, vous faites essentiellement null.Remarks, ce qui provoque l'erreur.

Vous devez changer votre code à ceci:

.FirstOrDefault(x => x.DocumentHandle == dm.DocumentHandle)?.Remarks 

Il y a deux différences ici:

  1. se sont débarrassés de l'endroit et déplacé le prédicat à l'appel FirstOrDefault. C'est juste une façon plus propre de faire ce que vous faisiez avant.

  2. Ajout du ? à la fin de l'appel FirstOrDefault. C'est le null propagation operator.

Ce qu'il fait est il se présente:

int foo; 
if (bar != null) 
{ 
    foo = bar.foo; 
} 

Dans ceci:

int foo = bar?.foo; 

Maintenant, s'il y a des éléments correspondants, statusRemarks sera égal à la première de Remarks. Sinon, statusRemarks sera null. L'opérateur de propagation nulle a été implémenté dans C# 6.0, qui est .Net 4.6 à partir de .NET 4.0. Il ne fonctionnera donc pas dans .Net 4.0.

Vous devez modifier votre recherche et mettre en œuvre un contrôle, comme suit:

var oList = (
    from dm in dbContext.document_master 
    join um in dbContext.user_master on dm.Alocated_CAA equals um.UserId 
    where (dm.DocumentHandle != null && dbContext.statushistories.Count(x => x.DocumentHandle == dm.DocumentHandle) > 0) 
    select new TaskLogReport 
    { 
     documentDate = dm.Document_Date, 
     documentHandle = dm.DocumentHandle, 
     fileNumber = dm.FileNumber, 
     statusRemarks = dbContext.statushistories.First(x.DocumentHandle == dm.DocumentHandle).Remarks 
    }).ToList(); 
+0

J'utilise Net Framework 4.L'opérateur de programmation 0 & null ne fonctionne pas. Après la réplication du même jeu de codes sur MS-SQL 2005, cela fonctionne correctement et le même code ne fonctionne pas avec MySQL. J'ai essayé d'installer le connecteur différent mais persiste même isssue –

+0

@ArifMohd Vérifiez l'édition. – stybl