Pergunta

Eu tenho um processo que está a importar do Excel planilhas eletrônicas, e de analisar os dados em minha objetos de dados.A fonte destes dados é muito questionável, como nós estamos nos movendo para o nosso cliente a partir de uma folha de cálculo baseado no gerenciamento de dados em um banco de dados gerenciados pelo sistema verifica os dados válidos.

Durante o meu processo de importação, faço básica verificações de sanidade dos dados para acomodar o quão ruim dados pode ser que estamos a importar, mas eu tenho o meu de validação geral que está sendo feito no DbContext.

Parte do que eu estou tentando fazer é que eu quero dar a Linha # na planilha de dados está ruim, então eles podem facilmente determinar o que eles precisam para corrigir, para obter o ficheiro a importar.

Assim que eu tiver os dados da planilha (model), e a Oportunidade que eles estão trabalhando com o banco de dados (opp), aqui está o pseudocódigo do meu processo:

foreach (var model in Spreadsheet.Rows) { // Again, pseudocode
    if(opp != null && ValidateModel(model, opp, row)) {
        // Copy properties to the database object

        // This is in a Repository-layer method, not directly in my import process.
        // Just written here for clarity instead of several nested method calls.
        context.SaveChanges(); 
    }
}

Posso dar mais do que o código aqui, se necessário, mas o problema vem na minha DbContext do ValidateEntity() (método de substituição de DbContext).

Novamente, não há nada de errado com o código que eu escrevi, tanto quanto eu sei, mas se uma Oportunidade que esta falha de nível de validação, então ele fica como parte dos não salvos objetos no context, o que significa que ele tenta repetidamente para obter validado a cada vez que o ValidateEntity() é chamado.Isso leva a uma repetição da mesma mensagem de Erro de Validação para cada linha depois que o problema inicial ocorre.

Existe uma maneira de [editar]obter o Contexto de deixar de tentar validar o objeto depois de falha de validação de uma vez[editar]?Eu sei que eu poderia esperar até o final e chamada de context.SaveChanges() uma vez no fim de contornar isso, mas eu gostaria de ser capaz de comparar isso com o que linha ele estiver no Banco de dados.

Para referência, eu estou usando o Entity Framework 6.1 com uma abordagem Code First.

EDITAR Tentar esclarecer ainda mais para Marc L.(incluindo uma atualização para o bloco de código acima)

Agora, a minha processo irá iterar através de várias linhas na folha de cálculo.A razão pela qual eu estou chamando de " meu Repositório camada com cada objeto para salvar, em vez de trabalhar com uma abordagem que apenas chamadas context.SaveChanges() uma vez que é para permitir-me a capacidade para determinar qual linha é o que está causando um erro de validação.

Eu estou feliz que meu DbContext personalizado ValidateEntity() métodos estão pegando a erros de validação, mas o problema reside no fato de que ele não está jogando o DbEntityValidationException para a mesma pessoa várias vezes.

Eu gostaria de de modo que, se o objeto de falha de validação de uma vez, o contexto não tenta salvar o objeto, independentemente de quantas vezes context.SaveChanges() é chamado.

Foi útil?

Solução

Sua pergunta não é um dupe (isto é sobre a poupança, não carregado entidades), mas você pode seguir Jimmy conselhos acima.Isto é, quando uma entidade é adicionado para o contexto em que ele é controlado na "adicionado" do estado e a única maneira de impedi-lo de re-validar é desanexando-o.É um MODO-de link interno, mas vou reproduzir o trecho de código:

dbContext.Entry(entity).State = EntityState.Detached;

No entanto, eu não acho que é o caminho que você quer seguir, porque você está usando exceções para gerenciar o estado desnecessariamente (as exceções são notoriamente caros).

Trabalhando a partir das informações dadas, eu usaria um conjunto de mais-solução baseada em:

  • modificar sua classe de modelo, de modo que ele contém um RowID que os registros de folha de cálculo original da linha (provavelmente há outras boas razões para ter isso também)
  • desligue-entidade de controle para o contexto (liga de detecção de mudanças, permitindo que cada Add() para ser O(1))
  • adicionar todas as entidades
  • chamada context.GetValidationErrors() e obter todos os seus erros de uma só vez, usando o referido RowID para identificar as linhas inválidas.

Você não indicar se o processo deve salvar o bom linhas ou rejeitar o arquivo como um todo, mas isto irá acomodar, isto é, se você precisa salvar o bom linhas, desconecte todas as linhas inválidas usando o código acima e em seguida SaveChanges().


Finalmente, se você deseja salvar o bom linhas e você está desconfortável com o conjunto baseado no método, seria melhor usar um novo DbContext para cada linha, ou pelo menos criar um novo DbContext depois de cada erro.O ADO.NET equipe insiste em que contexto a criação é "relativamente baixo" (desculpe, eu não tenho a citar estatísticas na mão para isso) para que isso não deve danificar a sua taxa de transferência muito.Mesmo assim, ele vai permanecer pelo menos O(n).Eu não culpo você, o gerenciamento de um grande contexto pode abri-lo a outros problemas também.

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