2011-04-17 3 views
4

Comment JOINIRE des tables sur des colonnes NULLable?LINQ-Joindre des tables sur des colonnes NULL

je suit LINQ-requête, RMA.fiCharge peut être NULL:

Dim query = From charge In Services.dsERP.ERP_Charge _ 
        Join rma In Services.dsRMA.RMA _ 
        On charge.idCharge Equals rma.fiCharge _ 
        Where rma.IMEI = imei 
       Select charge.idCharge 

je reçois une "conversion de type 'DBNull' taper 'entier' est pas valide" dans query.ToArray():

Dim filter = _ 
     String.Format(Services.dsERP.ERP_Charge.idChargeColumn.ColumnName & " IN({0})", String.Join(",", query.ToArray)) 

Donc, je pourrais ajouter un WHERE RMA.fiCharge IS NOT NULL dans la requête. Mais comment faire cela dans LINQ ou y a-t-il une autre option?

Merci d'avance.


Solution:

Le problème est que le DataSet ne supporte pas nullables-types, mais génère un InvalidCastException si vous interrogez les NULL-valeurs sur une colonne entière (grâce Martinho). La requête LINQ modifiée de dahlbyk fonctionne avec peu de modifications. Le DataSet génère une propriété booléenne pour chaque colonne avec AllowDbNull = True, dans ce cas IsfiChargeNull.

Dim query = From charge In Services.dsERP.ERP_Charge _ 
      Join rma In (From rma In Services.dsRMA.RMA _ 
         Where Not rma.IsfiChargeNull 
         Select rma) 
       On charge.idCharge Equals rma.fiCharge _ 
      Where rma.IMEI = imei 
      Select charge.idCharge 
+1

Utilisez-vous des entrées nullables? Pourquoi avez-vous tagué cela avec linq-to-objects? LINQ-to-Objects n'a pas de ** SQL **. –

+0

Non, le DataColumn dans l'ensemble de données typé est de type entier. –

+0

Voilà votre problème. Vous avez besoin d'ints nullable. –

Répondre

3

Avez-vous essayé d'ajouter le chèque null à votre clause where?

Dim query = From charge In Services.dsERP.ERP_Charge _ 
      Join rma In Services.dsRMA.RMA _ 
       On charge.idCharge Equals rma.fiCharge _ 
      Where rma.fiCharge <> Nothing AndAlso rma.IMEI = imei 
      Select charge.idCharge 

Si cela ne fonctionne pas, vous pouvez essayer quelque chose comme ceci:

Dim query = From charge In Services.dsERP.ERP_Charge _ 
      Join rma In (From rma in Services.dsRMA.RMA _ 
         Where rma.fiCharge IsNot Nothing 
         Select rma) 
       On charge.idCharge Equals rma.fiCharge _ 
      Where rma.IMEI = imei 
      Select charge.idCharge 
+0

Merci, la deuxième requête fonctionne après avoir remplacé 'rma.fiCharge <> Nothing' par' Not rma.IsfiChargeNull' :) –

0

Alors que vous pouvez utiliser LINQ à datasets pour résoudre ce problème, vous pourriez trouver de meilleures performances en utilisant les DataRelations prédéfinies à la place des jointures ad-hoc. Voir http://msdn.microsoft.com/en-us/library/dbwcse3d.aspx pour plus d'informations sur les relations de données. Si vous utilisez LINQ to Datasets, vous pouvez consulter notre bonus gratuit chapitre 14 sur eux au http://www.manning.com/marguerie/.

+0

Je ne pense pas que DataRelations soit beaucoup plus rapide que [LINQ-Joins car ils utilisent aussi des algorithmes de hachage pour lien les tables] (http://stackoverflow.com/questions/5551264/why-is-linq-join-so-much-faster-than-linking-with-where) mais LINQ est beaucoup plus flexible. –

+0

Je pense que ces optimisations avec l'algorithme de hachage s'appliquent uniquement si vous utilisez .Net 4+. Si vous utilisez 3.5, la DataRelation Dataset est la meilleure option. –

Questions connexes