Linq se joint à deux valeurs

Supposons que j'ai une list de {City, State} . À l'origine, il provenait de la database, et j'ai un location, mais maintenant je l'ai chargé en memory. Supposons que j'ai aussi une table de restaurants de restauration rapide qui a la ville et l'État dans le cadre du record. J'ai besoin d'une list d'établissements qui correspondent à la ville et à l'état.

NOTE: J'essaie de décrire un scénario simplifié; mon domaine d'activité est complètement différent.

Je suis venu avec la solution LINQ suivante:

 var establishments = from r in restaurants from l in locations where l.LocationId == id && l.City == r.City && l.State == r.State select r 

et je pense qu'il doit y avoir quelque chose de mieux. Pour commencer, j'ai déjà la ville / état en memory – donc revenir à la database uniquement pour avoir une jointure semble très inefficace. Je cherche un moyen de dire {r.City, r.State} match Any(MyList) où MyList est ma collection de City / State.

MISE À JOUR J'ai essayé de mettre à jour en fonction de la suggestion ci-dessous:

 List<CityState> myCityStates = ...; var establishments = from r in restaurants join l in myCityStates on new { r.City, r.State } equals new { l.City, l.State } into gls select r; 

et j'ai l'erreur de compilation suivante: Error CS1941 The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'. Error CS1941 The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'.

UPDATE 2 Le compilateur n'a pas aimé la class anonyme dans la jointure. Je l'ai fait explicite et il a cessé de se plaindre. Je verrai si ça marche vraiment le matin …

Il me semble que vous en avez besoin:

 var establishments = from r in restaurants join l in locations.Where(x => x.LocationId == id) on new { r.City, r.State } equals new { l.City, l.State } into gls select r; 

Eh bien, il n'y a pas beaucoup plus que vous pouvez faire, tant que vous vous fiez à une table de consultation, la seule chose que vous pouvez faire pour accélérer les choses est de mettre un index sur City and State.

L'instruction linq doit se traduire par une instruction SQL valide, où "Any" se traduirait par quelque chose comme:

 SELECT * FROM Restaurants where City in ('...all cities') 

Je ne sais pas si d'autres ORM donnent de meilleures performances pour ces types de scénarios que EF, mais il pourrait être utile d'étudier. EF n'a jamais eu de rumeur d'être rapide sur les lectures.

Edit: Vous pouvez aussi faire ceci:

 List<ssortingng> names = new List { "John", "Max", "Pete" }; bool has = customers.Any(cus => names.Contains(cus.FirstName)); 

cela produira la fonctionnalité IN ('value1', 'value2' …) nécessaire que vous cherchiez