Domanda

Ho un database semplice con due tabelle. Utenti e configurazioni. Un utente ha una chiave esterna per collegarla a una particolare configurazione.

Ho uno strano problema in cui la seguente query provoca sempre un join interno alla tabella di configurazione indipendentemente dal secondo valore del parametro. Per quanto ne so, anche se " UserConfiguration = " parte dell'inizializzazione dell'oggetto è condizionale, LINQ non lo vede e determina che una relazione è seguita in ogni caso.

Se rimuovo effettivamente l'ultima inizializzazione, tutto funziona come previsto. Non si unisce internamente quando loadConfiguration == false e si unisce quando loadConfiguration == true.

Qualcuno ha qualche idea al riguardo? Questa sintassi non funzionerà? L'unico pensiero che ho ora è di racchiudere il ritorno in un'istruzione if di base: volevo solo evitare le righe duplicate.

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();
    }
}

Grazie in anticipo,

Martin.

È stato utile?

Soluzione

Non credo che funzionerà così.

Suggerisco di dividerlo in 2 query distinte.

Probabilmente ci sono modi migliori, ma richiederebbe più "idraulici".

Altri suggerimenti

No, questo non funzionerà. Ho riscontrato problemi simili molte volte. La ragione di ciò ha a che fare con le espressioni in fase di compilazione rispetto alle condizioni in fase di esecuzione.

Potresti fare 2 query o se non ti dispiace unirti alla configurazione indipendentemente dal parametro loadConfiguration, puoi usare:

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

e quindi utilizzare Linq-to-Objects sul risultato.

Sostituisci .Single () con SingleOrDefault () e Linq passerà a un join esterno sinistro. Non so se nel tuo caso lo farà, ma in alcuni casi lo fa.

Modifica dint's vedi che Single era per l'intera query e non per la parte di configurazione:

prova questo:

     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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top