2010-06-01 8 views
3

Nous avons une table de base de données qui stocke l'emplacement de certains fichiers wave plus les méta-données associées. Il y a une clé étrangère (employeeid) sur la table qui lie à une table d'employés. Cependant, tous les fichiers wav ne concernent pas un employé, pour ces enregistrements, employeeid est null. Nous utilisons LinqToSql pour accéder à la base de données, la requête pour retirer tous les employés non liés dossiers de fichiers wav est la suivante:Comportement LinqToSql intéressant

var results = from Wavs in db.WaveFiles 
       where Wavs.employeeid == null; 

Sauf que ce ne renvoie aucun enregistrement, en dépit du fait qu'il ya des enregistrements où employeeid est nulle. Sur le profilage serveur sql j'ai découvert la raison pour laquelle aucun enregistrement sont retournés parce que LinqToSql tourne dans SQL qui ressemble beaucoup:

SELECT Field1, Field2 //etc 
FROM WaveFiles 
WHERE 1=0 

Évidemment, cela ne renvoie aucune ligne. Cependant, si je vais dans le concepteur DBML et supprimer l'association et enregistrer. Tout à coup, la même requête LINQ se transforme en

SELECT Field1, Field2 //etc 
FROM WaveFiles 
WHERE EmployeeID IS NULL 

I.e. S'il y a une association alors LinqToSql suppose que tous les enregistrements ont une valeur pour la clé étrangère (même si elle est nullable et la propriété apparaît comme intensible null sur l'entité WaveFile) et construit ainsi une clause where qui ne retournera aucun enregistrement .

Est-ce que quelqu'un sait s'il existe un moyen de conserver l'association dans LinqToSQL mais arrêter ce comportement. Une solution de contournement que je peux penser rapidement est d'avoir un champ calculé appelé IsSystemFile et le définir à 1 si employeeid est null et 0 sinon. Cependant cela semble un peu un hack pour contourner le comportement étrange de LinqToSQl et je préfère faire quelque chose dans le fichier DBML ou définir quelque chose sur la contrainte de clé étrangère qui empêchera ce comportement.

Répondre

0

La colonne est définie d comme:

[Column(Storage="_employeeid", DbType="Int")] 

La façon dont le tour tout en laissant l'association était de faire une jointure gauche de la collection de l'entité des employés.

5

Je pense que vous devriez vérifier votre fichier dbml. On dirait que Linq ne sait pas que employeeid est une colonne nullable. Ou regardez votre fichier .cs. Les attributs de cette colonne doit ressembler à ceci:

[Column(Storage="_employeeid", DbType="Int")] 

et non:

[Column(Storage="_employeeid", DbType="Int NOT NULL")] 
0

essayez ceci:

var results = from Wavs in db.WaveFiles 
       where DbNull.Value.Equals(Wavs.employeeid) 

une autre façon et bonne practe un beau est d'introduire un employé par défaut où chaque fichier wave est associé à, qui n'est pas associé à un employé réel