Por que é o Entity Framework desconsiderando o meu orderbys?
-
12-12-2019 - |
Pergunta
Eu sou a reconfiguração de uma aplicação que precisa para duplicar a alfabetização lógica de um antigo sistema de mainframe.No antigo sistema de mainframe, item de registro de alteração IDs são colocados em ordem alfabética De A A Z, e em seguida, começa com AA, AB, e assim por diante.Infelizmente SQL Server .NET quer colocar AA entre A e B, então eu estou tendo que saltar através de alguns aros.Eu estou tentando ordenar a alteração de IDs primeiro por ordem decrescente de comprimento e, em seguida, por colocar em ordem alfabética, em ordem decrescente.
Aqui está o método que eu estou usando para recuperar os dados:
protected internal IList<TeamViewModel> GetTeams(string recordId, string changeId)
{
var viewModels = (from x in repository.Teams
where x.RecordId == recordId && x.ChangeId.Length <= changeId.Length &&
(x.ChangeId.CompareTo(changeId) == -1 || x.ChangeId.CompareTo(changeId) == 0)
orderby x.ChangeId.Length descending, x.ChangeId descending, x.ChangeId descending
group x by x.TeamId into grp
select grp.FirstOrDefault())
.ToList()
.Select(TeamViewModel.FromEntity)
.ToList();
return viewModels;
}
Cada "Record" tem uma coleção de alterar registros e cada registro de alteração de um ChangeId propriedade e TeamId que fez a alteração.Eu estou tentando conseguir o "mais novo" (de acordo com o velho mainframe ordenação lógica) alterar o registro para cada distintas teamId.Em outras palavras, eu estou tentando solicitar os registros, agrupá-los por equipe e, em seguida, pegue o primeiro registro de cada grupo.
O repositório.Equipes de propriedade retorna um IQueryable que envolve o ObjectSet declarado em minha ObjectContext.
O que realmente sopra minha mente é que esta consulta funciona bem quando eu executar em Linqpad (com a configuração padrão) e muito esse método executa correctamente a partir de dentro testes de unidade, quando eu tiver injectado uma simulação do meu repositório para esta classe, o que eu tenho de instalação para emitir exatamente a mesma de dados que está no banco de dados SQL.
Mas quando esse método é executado em tempo de execução, ele se comporta como se a linha com o orderbys é completamente omitido e na verdade me dá os mesmos resultados que eu ge estanho Linqpad (com a configuração padrão) quando eu comente a linha com o orderbys.SQL Profiler mostra que o SQL gerado é quase impossível decifrar por um ser humano, mas que não contêm a palavra "ordem" em qualquer lugar.
Como nota final, quando eu configurar o Linqpad usar o meu EF-gerado dataset digitado dentro do meu projeto, montagem, eu obter os mesmos resultados que eu veja em tempo de execução, com resultados que aparecem como se o orderbys são desconsiderados.
Eu desejo que eu poderia mostrar os resultados reais, mas os dados são de propriedade, portanto, basta considerar que os resultados corretos, conforme previsto pela Linqpad e minha testes de unidade, contêm registros de alteração com Identificações como "Y" e "Z", onde, como o inexplicável (para mim) os resultados que eu vejo no meu projeto em tempo de execução são como "A" e "B".
Qualquer pessoa pode ver o que está ocorrendo aqui, e tão importante, o que eu preciso mudar para tornar esta função, como eu estou esperando?
Meu projeto é usando o entity framework 5.0 e estou usando o Linqpad 4.42.01.
Muito obrigado!
Solução
Grupo pela não garantia de manter a ordem original.Se você quer encomendar, você deve encomenda depois de o grupo.
Na verdade, não faz muito sentido por diante de um grupo, pois o grupo é garantido para alterar a ordem (a menos que haja apenas um único grupo).
Outras dicas
Eu vou fazer uma aposta cega...
Seu ChangeId são todos o mesmo comprimento.O banco de dados tem mapeado como uma coluna CHAR(10) ou algo, em vez de uma coluna VARCHAR, então é realmente "Um" e AB é realmente "AB ".Mainframes e COBOL e televisão arquivos com deslocamentos vêm à mente como a minha lógica.Se este for o caso, você teria de Trim() o ChangeId primeiro antes de começar o Comprimento.