Pregunta

Tengo una base de datos simple con dos tablas. Usuarios y configuraciones. Un usuario tiene una clave externa para vincularla a una configuración particular.

Tengo un problema extraño en el que la siguiente consulta siempre provoca una unión interna a la tabla de configuración, independientemente del segundo valor del parámetro. Por lo que puedo decir, a pesar de que " UserConfiguration = " parte de la inicialización del objeto es condicional, LINQ no lo ve y determina que se sigue una relación en cualquier caso.

Si realmente elimino esa última inicialización, todo funciona como se esperaba. No se une internamente cuando loadConfiguration == false y se une cuando loadConfiguration == true.

¿Alguien tiene alguna idea sobre esto? ¿Esta sintaxis simplemente no va a funcionar? El único pensamiento que tengo ahora es envolver el retorno en una declaración if básica: solo quería evitar las líneas duplicadas.

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

Gracias de antemano,

Martin.

¿Fue útil?

Solución

No creo que funcione así.

Sugiero dividirlo en 2 consultas distintas.

Probablemente hay mejores formas, pero requeriría más 'plomería'.

Otros consejos

No, esto no funcionará. Me he encontrado con problemas similares muchas veces. La razón de esto tiene que ver con expresiones en tiempo de compilación versus condiciones en tiempo de ejecución.

Puede hacer 2 consultas o, si no le importa unirse a la configuración, independientemente del parámetro loadConfiguration, puede usar:

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

y luego use Linq-to-Objects en el resultado.

Reemplace .Single () con SingleOrDefault () y Linq cambiará a una unión externa izquierda. No sé si en su caso lo hará, pero en algunos casos lo hace.

Editar dint's ver que Single fue para toda la consulta y no para la parte de configuración:

prueba esto:

     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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top