Pergunta

Eu queria saber se alguém tem uma boa solução para um problema que eu encontrei várias vezes durante os últimos anos.

Eu tenho um carrinho de compras e meu cliente solicita explicitamente que de ordem é significativa. Então eu preciso persistir a ordem para o DB.

A maneira óbvia seria a de simplesmente inserir alguns OrderField onde gostaria de atribuir o número de 0 a N e tipo-lo dessa forma.

Mas isso faria reordenação mais difícil e de alguma maneira eu sinto que esta solução é meio frágil e vai voltar para mim algum dia.

(eu uso C # 3,5 com NHibernate e SQL Server 2005)

Obrigado

Foi útil?

Solução

FWIW, eu acho que a maneira que você sugere (ou seja, cometer a ordem ao banco de dados) não é uma má solução para o seu problema. Eu também acho que é provavelmente o mais maneira mais segura / confiável.

Outras dicas

Ok aqui é a minha solução para tornar a programação isso mais fácil para qualquer um que acontece ao longo á esta discussão. o truque é ser capaz de atualizar todos os índices de ordem acima ou abaixo uma inserção / deleção em uma atualização.

Usando um numérico (inteiro) coluna na tabela, apoiado pela SQL consultas

CREATE TABLE myitems (Myitem TEXT, id INTEGER PRIMARY KEY, orderindex NUMERIC);

Para excluir o item em orderindex 6:

DELETE FROM myitems WHERE orderindex=6;    
UPDATE myitems SET orderindex = (orderindex - 1) WHERE orderindex > 6;

Para trocar dois itens (4 e 7):

UPDATE myitems SET orderindex = 0 WHERE orderindex = 4;
UPDATE myitems SET orderindex = 4 WHERE orderindex = 7;
UPDATE myitems SET orderindex = 7 WHERE orderindex = 0;

i. 0 não é usado, então use uma lo como um manequim para evitar ter um item ambíguo.

Para inserir a 3:

 UPDATE myitems SET orderindex = (orderindex + 1) WHERE orderindex > 2;
 INSERT INTO myitems (Myitem,orderindex) values ("MytxtitemHere",3)

A melhor solução é uma lista ligada Duplamente . O (1) em todas as operações com excepção de indexação. Nada pode indexar SQL rapidamente embora, exceto uma cláusula WHERE no item que você deseja.

0,10,20 tipos falhar. as colunas seqüência falhar. coluna sequência flutuador falhar em movimentos de grupo.

lista duplamente ligada é mesmas operações para adição, remoção, eliminação do grupo, além de grupo, movimento grupo. lista ligada única funciona ok também. Duplo ligado é melhor com SQL na minha opinião embora. Único ligada lista exige que você tenha a lista inteira.

Que tal usar uma implementação de lista ligada? Ter uma coluna o vai conter o valor (número de ordem) do próximo item. Eu acho que é de longe o mais fácil de usar ao fazer inserção de ordens no meio. Não há necessidade de numerar.

Infelizmente não há nenhuma bala mágica para isso. Você não pode garantimos a ordem de qualquer declaração SELECT sem uma cláusula ORDER BY. Você precisa adicionar a coluna e do programa em torno dele.

Eu não sei que eu recomendo a adição de lacunas na sequência da ordem, dependendo do tamanho de suas listas e os acessos no site, você pode ganhar muito pouco para a cabeça sobre de lidar com a lógica (você' d ainda precisa atender para a ocasião em que todas as lacunas têm sido utilizados para cima). Eu dar uma olhada para ver o que os beneficia isto lhe daria na sua situação.

Infelizmente não posso oferecer nada melhor, espero que isso ajudou.

Eu não recomendaria o A, AA, B, BA, abordagem BB em tudo. Há um monte de processamento extra envolvido para determinar a hierarquia e as entradas de inserção no meio não é divertido em tudo.

Basta adicionar um OrderField, inteiro. Não use lacunas, porque então você tem que quer trabalhar com um 'passo' não-padrão em sua próxima inserção meio, ou você vai ter que voltar a sincronizar sua lista em primeiro lugar, em seguida, adicione uma nova entrada.

Tendo 0 ... N é fácil de reordenar e se você pode usar métodos de matriz ou métodos Lista fora do SQL para reordenar a coleção como um todo, em seguida, atualize cada entrada, ou você pode descobrir onde você está inserindo, e um ou -1 cada entrada antes ou depois de que em conformidade.

Uma vez que você tem um pouco biblioteca escrita por ele, vai ser um pedaço de bolo.

Gostaria apenas de inserir um campo ordem. É a maneira mais simples. Se o cliente pode reordenar os campos ou você precisa inserir no meio em seguida, basta reescrever os campos de ordem para todos os itens em cada lote.

Se abaixo da linha você encontrar este limitante devido ao mau desempenho em inserções e atualizações, em seguida, é possível usar um campo varchar em vez de um inteiro. Isto permite a um nível bastante alto de precisão ao inserir. por exemplo, para inserir entre os itens 'A' e 'B' você pode inserir um item encomendado como 'AA'. Isto é quase certamente um exagero para um carrinho de compras no entanto.

Em um nível de abstração acima do carrinho Itens digamos CartOrder (que tem 1-n com CartItem) você pode manter um campo chamado itemOrder que poderia ser apenas uma vírgula - lista separada de id (PK) de cartItem registros relevantes. Vai ser na camada de aplicação que você precisa para analisar isso e organizar seus modelos de item de conformidade. A grande vantagem para esta abordagem será, em caso de reshufflings ordem, pode não haver alterações em objetos individuais, mas desde que a ordem é mantido como um campo de índice dentro das linhas da tabela de itens fim você terá que emitir um comando de atualização para cada um dos linhas atualizando seu campo de índice. Por favor, deixe-me saber suas críticas sobre esta abordagem, eu estou curioso para saber de que forma isso pode falhar.

Eu resolvi pragmaticamente como este:

  1. A ordem é definido na interface do usuário.

  2. O backend recebe uma solicitação POST que contém os IDs ea correspondente posição de cada item na lista.

  3. Eu iniciar uma transação e atualizar a posição para cada ID.

Concluído.

Assim ordenação é caro, mas a leitura da lista ordenada é super barato.

Eu recomendaria manter lacunas no número de ordem, então em vez de 1,2,3 etc, uso 10,20,30 ... Se você precisa apenas inserir mais um item, você pode colocá-lo em 15, em vez de reordenação tudo naquele ponto.

Bem, eu diria que a resposta curta é:

Criar uma chave primária de autoidentity na tabela de cartcontents, em seguida, inserir linhas na ordem correta de cima para baixo. Em seguida, selecionando a partir da tabela com a ordem pela coluna autoidentity chave primária iria dar-lhe a mesma lista. Ao fazer isso você tem que eliminar todos os itens e reinsira, em seguida, em caso de alterações para o conteúdo do carrinho. (Mas isso ainda é bastante uma maneira limpa de fazê-lo) Se isso não for possível, em seguida, ir com a coluna de ordem como sugerido por outros.

Quando eu uso Hibernate, e necessidade de salvar a ordem de um @OneToMany, eu uso um Map e não um List.

@OneToMany(fetch = FetchType.EAGER, mappedBy = "rule", cascade = CascadeType.ALL)
@MapKey(name = "position")
@OrderBy("position")
private Map<Integer, RuleAction>    actions             = LazyMap.decorate(new LinkedHashMap<>(), FactoryUtils.instantiateFactory(RuleAction.class, new Class[] { Rule.class }, new Object[] { this }));

Neste exemplo Java, position é uma propriedade Integer de RuleAction por isso a ordem é mantido dessa forma. Eu acho que em C # isso ficaria bastante semelhante.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top