2009-09-01 6 views
1

Voici a n ex a mple:LINQ et nullables relations clés affectant le fonctionnement UNION

Lets s a y Ih a ve 3 t a Bles, pays, les gens a nd Villes. Enregistrements de villes h a ve a non-nul a champ de clé étrangère identifiable a pays. Les gens enregistre h a ve a null a ble champ de clé étrangère identifiant a pays - ils m a y être de a n E Europe de l'arrière pays a a n e t a n'existe plus.

I w a nt à Cre a te a liste combinée des pays de a liste des personnes a nd a liste des villes:

var people = dbContext.People.Where(...); 
var cities = dbContext.Cities.Where(...); 

var countries = cities.Select(c=>c.Country); 
countries = countries.Union(people.Select(p=>p.Country)); 

Le problème vient de a e t l a ligne st. Depuis pas a personnes ll enregistre h a ve a m a tching record du pays, LINQ est (correctement) cre a ting a requête e t a assure qu'il y aura a ligne la valeur NULL pour chaque personne apatride. Avec a débogueur il a ppe a rs cela se fait par cre a ting a n ENTR a colonne factice c a ll "[Test]"

SELECT [t2].[test], [t2].[CountryID], [t2].[Name] 
FROM [dbo].[People] AS [t0] 
LEFT OUTER JOIN (
    SELECT 1 AS [test], [t1].[CountryID], [t1].[Name] 
    FROM [dbo].[Countries] AS [t1] 
    ) AS [t2] ON [t2].[CountryID] = [t0].[CountryID] 

Alors e a t extr a colonne [Test] est retiré en silence (le résultat est identifié a s IQuery a ble) du côté du code, du côté SQL, il est très certainement là, a nd aboutit à la requête étant rejetée quand je l'union avec a norme a l Sélection du pays st a tement.

Dans la nageoire a l c a se je ne w a nt ou besoin des lignes fictives extr a - en plein progr a m J'ai a LRE a dy inclus people.Where(p=>p.CountryID != null).Select(p=>p.Country) a s et a s essayer p=>Country != null.

Cependant, Linq ne reconnaît pas le a t cela empêchera les lignes nulles a et donc insère toujours la colonne de test. a de la colonne de test est invisible, je h a ai pas évident w a y de "supprimer" à partir wh a t est par ailleurs rapporté a de a n IQuery a objet ble.Le résultat final est l'erreur de temps d'exécution a sur ma construction UNION h a ving a n non a l nombre de colonnes.

Comment c a n je force a n INNER JOIN sur mon null a ble tionship rel a, ou autrement m a ke le travail syndical a s I w a nt en excluant la colonne de test invisible?

Répondre

1

Je sais que vous utiliseriez idéalement les relations dans le mappage, mais cela pourrait être une bonne solution.

var people = dbContext.People.Where(...); 
var cities = dbContext.Cities.Where(...); 

var countryIds = 
    cities 
    .Select(c => c.CountryID) 
    .Union(people 
    .Select(p => p.CountryID) 
    .Where(cID => cID.HasValue) 
    .Select(cID => cID.Value)); 

var countries = dbContext.Countries 
    .Where(c => countryIds.Contains(c.CountryID)); 
Questions connexes