2016-06-07 1 views
1

J'ai la requête LINQ suivante:EF4 ajoutant est la clause nulle sur la clause where

var fileDocuments = (
    from doc in fileUploads 
    from invoice in 
     (
      from inv in _dbContext.SupplierInvoiceHeaders 
      where inv.InvoiceDocumentId == doc.ID || inv.JobSheetInvoiceId == doc.ID 
      select inv 
      ).DefaultIfEmpty() 
    join pos in _dbContext.PurchaseOrders on invoice.PurchaseOrder.PurchaseOrderId equals pos.PurchaseOrderId into poss 
    from po in poss.DefaultIfEmpty() 
    join hdf in _dbContext.HelpDeskFaults on po.HelpdeskFaultId equals hdf.ID into hdfpo 
    from hs in hdfpo.DefaultIfEmpty() 
    join store1 in _dbContext.Stores on hs.StoreID equals store1.ID into hsf 
    from hdfStore in hsf.DefaultIfEmpty() 
    join js in _dbContext.JobSheets on invoice.SupplierInvoiceHeaderId equals js.SupplierInvoiceHeaderID into jss 
    from jobSheets in jss.DefaultIfEmpty() 
    join ch in _dbContext.ChildProjects on po.ChildProjectId equals ch.ID into chs 
    from childProjects in chs.DefaultIfEmpty() 
    join ph in _dbContext.ProjectHeaders on childProjects.ProjectHeaderID equals ph.ID into phs 
    from projectHeaders in phs.DefaultIfEmpty() 
    join ppmsl in _dbContext.PpmScheduleLines on projectHeaders.PPMScheduleRef equals ppmsl.ID into ppsmsls 
    from ppmScheduleLines in ppsmsls.DefaultIfEmpty() 
    join ss2 in _dbContext.Stores on ppmScheduleLines.StoreID equals ss2.ID into ssts 
    from store2 in ssts.DefaultIfEmpty() 
    select new 
    { 
     doc.ID, 
     JobSheetId = jobSheets.DocumentID, 
     doc.Name, 
     doc.DateCreated, 
     doc.StoreID, 
     StoreName = doc.Store.Name, 
     DocumentType = doc.DocumentType.Name, 
     doc.DocumentTypeID, 
     HelpDeskFaultStoreName = hs.Store.Name, 
     DocStoreName = doc.Store.Name, 
     PPMScheduleLinesStoreName = ppmScheduleLines.Store.Name, 
     PIR = invoice.PurchaseInvoiceReference 
    }); 


    fileDocuments = fileDocuments.Where(x => x.PIR == jobSearchParams.PIR); 

La clause where générée ressemble à ceci:

WHERE ([Extent2].[fld_str_PIR] = @p__linq__0) OR (([Extent2].[fld_str_PIR] IS NULL) AND (@p__linq__0 IS NULL)) 

Je ne comprends pas pourquoi il ajoute les clauses IS NULL.

Répondre

1

Il les ajoute car votre jobSearchParams.PIR peut être nul. Dans le cas où il est nul, EF supposera que vous voulez retourner les lignes où fld_str_PIR est nul. Mais dans sql, votre ne peut pas comparer avec null en utilisant « = » opérateur:

WHERE ([Extent2].[fld_str_PIR] = @p__linq__0) -- doesn't work if @p__linq__0 is null 

C'est la raison pour laquelle il gère ce cas pour vous et génère la requête correcte pour les deux cas - que ce soit jobSearchParams.PIR est nulle ou non.

+0

Est-ce que de toute façon je peux juste générer une vérification d'égalité sans la clause IS NULL non désirée? – dagda1

+0

S'il est de type nullable (par exemple chaîne, int? Etc) - j'en doute. _Vous pourriez savoir que cela ne peut jamais être nul, mais EF ne peut pas le savoir et je ne suis pas sûr qu'il existe un moyen de lui dire qu'il ne peut pas être nul. Si le type est nullable (int?), Vous pouvez d'abord affecter sa valeur à une variable locale non nulle du même type (int). Cependant, quel genre de problème avez-vous avec cela? – Evk

+0

Je ne comprends pas tout ce que je veux faire est de générer une clause where comme: '' 'WHERE (. [Extent2] [fld_str_PIR] = @ p__linq__0))' '' '' 'jobSearchParams.PIR'' 'ne sera jamais nul. – dagda1

0

Après charge de la recherche, je trouve un autre poste qui a mis en évidence le paramètre UseDatabaseNullSemantics:

context.Configuration.UseDatabaseNullSemantics = true;

ce paramètre est activé, ma requête est exécutée dans 900ms au lieu de temporiser.