Pergunta

Eu estive olhando alguns ganchos de auditoria com Entity Framework. Muitos deles mostram / novas comparações valor antigo. Isso faz ótimo para uma trilha de auditoria, mas eu estou olhando para objetos de instantâneo.

Por exemplo ... Vamos dizer que eu tenho um aplicativo que gerencia produtos. Um produto tem vários atributos e outros objetos associados. Digamos que eu mudar um objeto 10 vezes. Vamos dizer também que é importante que eu possa ver telas dessas mudanças objeto (não uma trilha de auditoria, mas o que a tela realmente parecia em um só ler formato). O que eu estou interessado é ser capaz de recuperar o objeto do produto EF original (com todos os dados associados) para todos os 10 dessas alterações (dependendo de qual Quero ver) e usar isso para se ligam a minha tela.

Se eu estou usando SQL Server, que tipo devo usar para o objeto serializado hoje (XML, gota, etc)? Faz sentido fazer isso?

Foi útil?

Solução

Vamos ver. Você tem um requisito de ter um gráfico de objeto e serializá-lo no banco de dados em um formato que permitirá que você se materializar mais tarde. Eu acho que existem ferramentas que fazem exatamente isso. Um deles, parece-me, é o Entity Framework.

O que você quer fazer é uma coisa muito comum. Considere um motor wiki. O wiki precisa ter uma revisão dica que todo mundo vê, além de revisões de trás de cada documento. O wiki também precisa ser capaz de exibir uma revisão de volta em exatamente da mesma maneira que uma revisão dica é exibida. Portanto, o mesmo formato de armazenamento deve ser usado para ambos.

Eu gostaria de propor que você permitir que todos os seus tipos de entidade a ser versionadas. Quando você editar um tipo de entidade, você irá editar a revisão ponta e armazenar uma revisão volta contendo os valores anteriores. (A razão que você editar a revisão ponta em vez de inserir uma nova dica é porque outros objetos, que não estão actualmente materializadas em um ObjectContext, pode conter links para a ponta que você gostaria de preservar como links para a ponta, ao invés de links para a revisão de volta.)

Se necessário, você pode particionar as tabelas SQL Server para que as revisões das costas são armazenados em um grupo de arquivo diferente. Isso permitiria que você backup as revisões de ponta e revisões traseiras separadamente.

Outras dicas

Primeiro você precisa adicionar um conjunto de propriedades para suas tabelas:

  • Version -. Tempo da última modificação (também pode ser autoincremental balcão em vez do tempo)
  • LastModifiedBy -. De referência para o usuário que fez a última modificação (se você armazenar isso)

Em seguida, você tem várias opções sobre como armazenar seu histórico de versões. Você pode

  1. Criar uma nova tabela para cada uma das principais tabelas que você deseja armazenar o histórico de. Que as tabelas de história terá todos os mesmos campos como a tabela principal, mas chaves primárias e estrangeiras não será aplicada. Para cada chave estrangeira também armazenar versão de entrada referenciada no tempo versão foi criado.

  2. ou você pode serializar tudo interessante sobre a sua entidade e armazenar todos os que serializado blobs para todas as entidades que você quer para a versão em uma tabela história global (Eu pessoalmente prefiro primeira abordagem).

Como você encher suas mesas de história? atualizar e excluir os gatilhos via.

  • Na atualização gatilho para a sua entidade - copiar todos os valores anteriores à mesa de história. Para cada chave estrangeira - também copiar atual Versão de entidade referenciada
  • .
  • Em disparador de exclusão -., Basicamente, fazer o mesmo

Note que cada vez mais modernos sistemas realmente não nada de exclusão. Eles só marca as coisas como excluídos. Se você gostaria de seguir este padrão (que tem vários benefícios.) - em vez de excluir add bandeira IsDeleted às suas entidades (é claro que você então tem que filtro eliminado entidades em todos os lugares)

Como você vê a sua história? Basta usar tabela de histórico, uma vez que tem todas as mesmas propriedades que a tabela principal - não deve ser um problema. Mas - ao expandir chaves estrangeiras - garantir que entidade referenciada versão é o mesmo que você armazena em sua tabela de histórico. Se não é - você precisa ir para a tabela Histórico de que os valores de entidade e agarrar referenciados lá. Desta forma, você sempre terá um instantâneo de como entidade parecia naquele momento, incluindo todas as referências.

Além de tudo acima - você também pode restaurar o estado da sua entidade para qualquer versão anterior.

Note que esta implementação, enquanto fácil, pode consumir algum espaço, porque ele armazena snapshot , não só mudanças que estão sendo feitas. Se você quiser apenas mudanças de loja - no gatilho de atualização é possível detectar quais campos foi alterada, serializar-los e armazenar na tabela história global. Dessa forma, você pode, pelo menos show em interface com o usuário o que foi alterado e por quem (embora você pode ter problemas para reverter para uma versão anterior).

Em um projeto que eu construído recentemente usamos nós conectado ao método SaveChanges na classe DbContext. Isso nos deu acesso a uma instância da classe ChangeTracker. Chamando ChangeTracker.Entries() dá-lhe acesso a uma lista de DbEntityEntry. DbEntityEntry tem as seguintes propriedades e métodos interessantes:

  • State - é o objeto recém-criado, modificado ou sendo excluído
  • Entity - uma cópia do objeto, tal como está
  • CurrentValues - uma enumeração da editado valorizado
  • OriginalValues - uma enumeração dos valores originais

Nós criamos um conjunto de Poços para conjuntos de alterações e mudanças que nós poderíamos então acesso através de EF. Isto permitiu que nossos usuários para mudanças no nível de campo vista juntamente com as datas e os usuários responsáveis.

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