2008-11-21 5 views
0

J'ai une base de données simple avec deux tables. Utilisateurs et configurations. Un utilisateur a une clé étrangère pour le lier à une configuration particulière.LINQ To SQL Weird Join Issue

J'ai un problème étrange où la requête suivante provoque toujours une jointure interne à la table de configuration indépendamment de la deuxième valeur de paramètre. Pour autant que je sache, même si la partie "UserConfiguration =" de l'initialisation de l'objet est conditionnelle, LINQ ne voit pas cela et détermine qu'une relation est suivie dans tous les cas.

Si je supprime réellement cette dernière initialisation, le tout fonctionne comme prévu. Il ne joint pas interne lorsque loadConfiguration == false et il se joint lorsque loadConfiguration == true.

Quelqu'un a-t-il des idées à ce sujet? Cette syntaxe ne fonctionne-t-elle pas? La seule pensée que j'ai maintenant est d'envelopper le retour dans une déclaration de base si - je voulais juste éviter les lignes en double.

public UserAccount GetByUsername(string username, bool loadConfiguration) 
{ 
    using (Database database = new Database()) 
    { 
     if (loadConfiguration) 
     { 
      DataLoadOptions loadOptions = new DataLoadOptions(); 
      loadOptions.LoadWith<User>(c => c.Configuration); 
      database.LoadOptions = loadOptions; 
     } 

     return (from c in database.Users 
       where c.Username == username 
       select new UserAccount 
       { 
        ID = c.ID, 
        ConfigurationID = c.ConfigurationID, 
        Username = c.Username, 
        Password = c.Password.ToArray(), 
        HashSalt = c.HashSalt, 
        FirstName = c.FirstName, 
        LastName = c.LastName, 
        EmailAddress = c.EmailAddress, 

        UserConfiguration = (loadConfiguration) ? new ApplicationConfiguration 
        { 
         ID = c.Configuration.ID, 
         MonthlyAccountPrice = c.Configuration.MonthlyAccountPrice, 
         TrialAccountDays = c.Configuration.TrialAccountDays, 
         VAT = c.Configuration.VAT, 
         DateCreated = c.Configuration.DateCreated 

        } : null 

       }).Single(); 
    } 
} 

Merci à l'avance,

Martin.

Répondre

0

Je ne pense pas que cela fonctionnera comme ça.

Je suggère de le diviser en 2 requêtes distinctes.

Il y a probablement de meilleurs moyens, mais cela nécessiterait plus de «plumage».

0

Non, cela ne fonctionnera pas. J'ai rencontré des problèmes similaires plusieurs fois. La raison de cela est liée aux expressions au moment de la compilation et aux conditions au moment de l'exécution.

Vous pouvez faire 2 requêtes ou si vous ne me dérange pas se joindre à la configuration indépendamment du paramètre loadConfiguration, vous pouvez utiliser:

var q = (from c in database.Users 
       where c.Username == username 
       select c).Single(); 

puis utiliser LINQ to Objects sur le résultat.

0

Remplacez .Single() par SingleOrDefault() et Linq passera à une jointure externe gauche. Je ne sais pas si dans votre cas, il le fera, mais dans certains cas, il le fait.

Modifier DINT de voir unique était pour toute requête et non pour la partie de configuration:

essayez ceci:

 UserConfiguration = (loadConfiguration && c.Configuration != null) ? new ApplicationConfiguration 
    { 
      ID = c.Configuration.ID, 
      MonthlyAccountPrice = c.Configuration.MonthlyAccountPrice, 
      TrialAccountDays = c.Configuration.TrialAccountDays, 
      VAT = c.Configuration.VAT, 
      DateCreated = c.Configuration.DateCreated 
     } : null