Estou tentando salvar os detalhes dos funcionários, que têm referências com a cidade. Mas sempre que tento salvar meu contato, que é validado, recebo a exceção "ADO.Net Entity Framework Um objeto de entidade não pode ser referenciado por várias instâncias do IEntityChangeTracker"
Eu tinha lido muitos posts, mas ainda não entendi exatamente o que fazer ... meu código de clique no botão Salvar é mostrado abaixo
protected void Button1_Click(object sender, EventArgs e)
{
EmployeeService es = new EmployeeService();
CityService cs = new CityService();
DateTime dt = new DateTime(2008, 12, 12);
Payroll.Entities.Employee e1 = new Payroll.Entities.Employee();
Payroll.Entities.City city1 = cs.SelectCity(Convert.ToInt64(cmbCity.SelectedItem.Value));
e1.Name = "Archana";
e1.Title = "aaaa";
e1.BirthDate = dt;
e1.Gender = "F";
e1.HireDate = dt;
e1.MaritalStatus = "M";
e1.City = city1;
es.AddEmpoyee(e1,city1);
}
e Código Employeeservice
public string AddEmpoyee(Payroll.Entities.Employee e1, Payroll.Entities.City c1)
{
Payroll_DAO1 payrollDAO = new Payroll_DAO1();
payrollDAO.AddToEmployee(e1); //Here I am getting Error..
payrollDAO.SaveChanges();
return "SUCCESS";
}
Form
(no entanto, apenas representa uma unidade de trabalho) porThread
(porqueDbContext
não é garantido que seja seguro para threads).As etapas para reprodução podem ser simplificadas para isso:
Código sem erro:
Usar apenas um
EntityContext
pode resolver isso. Consulte outras respostas para outras soluções.fonte
Este é um encadeamento antigo, mas outra solução, que eu prefiro, é apenas atualizar o cityId e não atribuir o modelo de furo City ao Employee ... para fazer com que o Employee se pareça com:
Então basta atribuir:
fonte
Como alternativa à injeção e, pior ainda, ao Singleton, você pode chamar o método Detach antes de Adicionar.
Enquadramento da entidade 6:
((IObjectContextAdapter)cs).ObjectContext.Detach(city1);
Enquadramento da entidade 4:
cs.Detach(city1);
Existe ainda outra maneira, caso você não precise do primeiro objeto DBContext. Basta envolvê-lo usando a palavra-chave:
fonte
dbContext1.Entry(backgroundReport).State = System.Data.Entity.EntityState.Detached
'para desanexar e, em seguida, fui capaz de usardbContext2.Entry(backgroundReport).State = System.Data.Entity.EntityState.Modified;
para atualizar. Trabalhou como um sonhoEu tive o mesmo problema, mas meu problema com a solução do @ Slauma (embora ótimo em alguns casos) é que ele recomenda que eu transmita o contexto para o serviço, o que implica que o contexto está disponível no meu controlador. Isso também força o acoplamento rígido entre meu controlador e as camadas de serviço.
Estou usando a Injeção de Dependência para injetar as camadas de serviço / repositório no controlador e, como tal, não têm acesso ao contexto do controlador.
Minha solução foi fazer com que as camadas de serviço / repositório usassem a mesma instância do contexto - Singleton.
Classe Singleton de contexto:
Referência: http://msdn.microsoft.com/en-us/library/ff650316.aspx
e http://csharpindepth.com/Articles/General/Singleton.aspx
Classe de Repositório:
Existem outras soluções, como instanciar o contexto uma vez e transmiti-lo aos construtores de suas camadas de serviço / repositório ou outra que li sobre o que está implementando o padrão da Unidade de Trabalho. Tenho certeza que existem mais ...
fonte
No meu caso, eu estava usando o ASP.NET Identity Framework. Eu tinha usado o
UserManager.FindByNameAsync
método interno para recuperar umaApplicationUser
entidade. Eu tentei fazer referência a essa entidade em uma entidade recém-criada em uma diferenteDbContext
. Isso resultou na exceção que você viu originalmente.Resolvi isso criando uma nova
ApplicationUser
entidade apenas comId
oUserManager
método from e fazendo referência a essa nova entidade.fonte
Eu tinha o mesmo problema e poderia resolver criando uma nova instância do objeto que estava tentando atualizar. Depois passei esse objeto para o meu repositório.
fonte
Nesse caso, o erro é muito claro: o Entity Framework não pode rastrear uma entidade usando várias instâncias de
IEntityChangeTracker
ou, normalmente, várias instâncias deDbContext
. As soluções são: use uma instância deDbContext
; acessar todas as entidades necessárias por meio de um único repositório (dependendo de uma instância doDbContext
); ou desativar o rastreamento de todas as entidades acessadas por um repositório que não seja o que gera essa exceção específica.Ao seguir uma inversão do padrão de controle na .Net Core Web API, frequentemente descubro que tenho controladores com dependências como:
e uso como
Como todos os três repositórios dependem de
DbContext
instâncias diferentes por solicitação, tenho duas opções para evitar o problema e manter repositórios separados: altere a injeção do DbContext para criar uma nova instância apenas uma vez por chamada:ou, se a entidade filha estiver sendo usada somente para leitura, desative o rastreamento nessa instância:
fonte
Use o mesmo objeto DBContext ao longo da transação.
fonte
Eu encontrei esse mesmo problema depois de implementar a IoC para um projeto (ASP.Net MVC EF6.2).
Normalmente, eu inicializava um contexto de dados no construtor de um controlador e usava o mesmo contexto para inicializar todos os meus repositórios.
No entanto, o uso da IoC para instanciar os repositórios fez com que todos tivessem contextos separados e comecei a receber esse erro.
Por enquanto, voltei a apenas atualizar os repositórios com um contexto comum, enquanto penso em uma maneira melhor.
fonte
Foi assim que encontrei esse problema. Primeiro, preciso salvar o meu,
Order
que precisa de uma referência à minhaApplicationUser
tabela:O problema é que estou inicializando um novo ApplicationDbContext para salvar minha nova
Order
entidade:Portanto, para resolver o problema, usei o mesmo ApplicationDbContext em vez de usar o UserManager interno do ASP.NET MVC.
Em vez disso:
Eu usei minha instância existente ApplicationDbContext:
fonte
Origem do erro:
Espero que alguém economize um tempo precioso
fonte