Pergunta

Eu tenho um banco de dados simples com duas mesas. Usuários e configurações. Um usuário tem uma chave estrangeira para vinculá-lo a uma configuração particular.

Estou tendo um problema estranho onde a seguinte consulta sempre causa uma junção interna para a tabela de configuração, independentemente do valor do segundo parâmetro. Tanto quanto eu posso dizer, mesmo que o "UserConfiguration =" parte do objeto de inicialização é condicional, LINQ não vê que e determina que um relacionamento é seguido em qualquer caso.

Se eu realmente remover a última inicialização, a coisa toda funciona como esperado. Não junção interna quando loadConfiguration == false e se junta ao loadConfiguration == true.

Alguém tem alguma idéia sobre isso? É esta sintaxe simplesmente não vai funcionar? O único pensamento que tenho agora é para embrulhar o retorno em um básico if -. Eu só queria evitar as linhas 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();
    }
}

Agradecemos antecipadamente,

Martin.

Foi útil?

Solução

Eu não acho que ele vai trabalhar assim.

Eu sugiro dividindo-o em 2 consultas distintas.

Existem provavelmente melhores maneiras, mas isso exigiria mais 'plumbling'.

Outras dicas

Não, isso não vai funcionar. Já corri em problemas semelhantes muitas vezes. A razão para isso tem a ver com expressões em condições de tempo versus compilação em tempo de execução.

Você pode fazer 2 perguntas ou se você não se importa se juntar à configuração independentemente do parâmetro loadConfiguration, você poderia usar:

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

e, em seguida, usar Linq-to-Objects no resultado.

Substituir .Single () com SingleOrDefault () e Linq irá mudar para uma junção externa esquerda. Eu não sei se no seu caso ele vai fazê-lo, mas em alguns casos ele faz.

Editar DINT ver o single foi para toda a consulta e não para a parte de configuração:

tente o seguinte:

     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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top