Question

J'ai une base de données simple avec deux tables. Utilisateurs et configurations. Un utilisateur a une clé étrangère pour la lier à une configuration particulière.

Je rencontre un problème étrange dans lequel la requête suivante provoque toujours une jointure interne à la table de configuration, quelle que soit la valeur du deuxième paramètre. Autant que je sache, même si le "UserConfiguration =" une partie de l'initialisation de l'objet est conditionnelle, LINQ ne le voit pas et détermine qu'une relation est suivie dans tous les cas.

Si je supprime réellement cette dernière initialisation, tout fonctionne comme prévu. Elle ne fait pas de jointure interne lorsque loadConfiguration == false et elle ne se joint pas lorsque loadConfiguration == true.

Quelqu'un a des idées à ce sujet? Cette syntaxe ne fonctionne-t-elle pas? La seule pensée que j’ai à l’heure est d’envelopper le retour dans une déclaration if simple - je voulais simplement é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 d'avance,

Martin.

Était-ce utile?

La solution

Je ne pense pas que cela fonctionnera comme ça.

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

Il existe probablement de meilleurs moyens, mais cela nécessiterait davantage de "marmotte".

Autres conseils

Non, cela ne fonctionnera pas. J'ai rencontré des problèmes similaires à plusieurs reprises. La raison en 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 cela ne vous dérange pas de rejoindre la configuration quel que soit le paramètre loadConfiguration, vous pouvez utiliser:

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

puis utilisez Linq-to-Objects sur le résultat.

Remplacez .Single () par SingleOrDefault () et Linq basculera vers une jointure externe gauche. Je ne sais pas si, dans votre cas, cela se fera, mais dans certains cas, c'est le cas.

Editez voir que le single était pour la requête entière et non pour la partie 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top