2008-10-26 5 views
0

Dans ma base de données, les concessions ont une relation plusieurs-à-un avec les entreprises (chaque concession a un ID de société). SqlMetal a capturé cette relation et a généré les classes appropriées, de sorte que chaque concession a un élément Firm. Je suis contre une requête de liaison (ici simplifiée) qui retourne une liste de concessions ainsi que des informations sur l'entreprise correspondante:Comment gérer correctement les clés étrangères nulles dans Linq to SQL?

From c as Concession in Db.Concessions _ 
Select _ 
    c.ConcessionID, _ 
    c.Title, _ 
    c.Firm.Title 

Le problème est que, dans certains cas, une concession n'a pas été attribué à une entreprise (c .FirmID est nul), alors c.Firm est rien et je reçois Object not set to an instance etc.

Je peux contourner ce problème en faisant une jointure comme suit:

From c As Concession In Db.Concessions _ 
Join f As Firm In Db.Firms On f.FirmID Equals c.FirmID _ 
Select _ 
    c.ConcessionID, _ 
    c.Title, _ 
    Firm_Title = f.Title 

cela ne jette pas une erreur quand FirmID est null (Firm_Title est juste une chaîne vide), mais c'est pas élégant: il n'est pas orienté objet, et ne tire pas parti de toute l'intelligence relationnelle que Linq to SQL a déjà capturée.

Y a-t-il une manière plus gracieuse de faire face à cette situation?

Répondre

1

@James Curran: Je reçois l'erreur à chaque fois que la requête est exécutée - par ex. si je lui envoie une grille, ou si je lui applique .ToList.

VB.NET a une nouvelle syntaxe ternaire vraie (encore plus verbeuse que C#). Cela fonctionne en fait:

From c As Concession In db.Concessions _ 
Select _ 
    c.ConcessionID, _ 
    c.Title, _ 
    Firm_Title = If(c.Firm IsNot Nothing, c.Firm.Title, String.Empty) _ 

Je ne suis pas vraiment satisfait de cette approche - il est une douleur d'avoir à faire avec tous les domaines que je pourrais utiliser à partir de la table étrangère. Je suis curieux de savoir pourquoi votre requête fonctionne et la mienne ne l'est pas. Votre DataContext est-il généré par SqlMetal? La relation est-elle déduite de la base de données?

+0

Je pense que vous pouvez faire alternativement: if (c.Firm.Title, String.Empty) – Kevin

+0

Non, cela jette "Référence de l'objet non défini à une instance d'un objet" si c.Firm est rien. –

3

Où allez-vous obtenir l'erreur?

Je viens de faire une même requête LINQ (en VB.Net), et il a bien fonctionné (réglage titre à null)

Vous aurez plus tard pour traiter avec le titre étant nul, mais ce n'est pas vraiment un Problème LINQ Et même cela peut être facilement traiter en C#. L'équivalent dans Vb.net serait d'utiliser le Iif(), mais je n'ai pas réussi à le faire fonctionner.

0

son fonctionne parce qu'il sélectionne une chaîne nulle et non une relation nulle.

0

Traiter dans le constructeur de l'objet

Public Property office() As String 
      Get 
       Return _office 
      End Get 
      Set(ByVal value As String) 
       If value IsNot Nothing Then 
        _office = value 
       Else 
        _office = String.Empty 
       End If 
      End Set 
     End Property 
+0

Le constructeur est auto-généré par SqlMetal, et je voudrais le garder comme ça. –