J'essaie de sauvegarder les détails de l'employé, qui ont des références avec City. Mais chaque fois que j'essaie d'enregistrer mon contact, qui est validé, j'obtiens l'exception "ADO.Net Entity Framework Un objet entité ne peut pas être référencé par plusieurs instances de IEntityChangeTracker"
J'avais lu tellement de messages mais je ne savais toujours pas exactement quoi faire ... mon code de clic sur le bouton Enregistrer est donné ci-dessous
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);
}
et code de service aux employés
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
(quoi qu'il arrive , cela ne représente qu'une unité de travail) parThread
(car ilDbContext
n'est pas garanti d'être threadsafe).Les étapes de reproduction peuvent être simplifiées à ceci:
Code sans erreur:
Un seul
EntityContext
peut résoudre ce problème. Référez-vous à d'autres réponses pour d'autres solutions.la source
C'est un ancien thread, mais une autre solution, que je préfère, consiste simplement à mettre à jour le cityId et à ne pas attribuer le modèle de trou City à Employee ... pour ce faire, l'employé devrait ressembler à:
Ensuite, il suffit d'assigner:
la source
Alternativement à l'injection et encore pire à Singleton, vous pouvez appeler Detach méthode avant Add.
EntityFramework 6:
((IObjectContextAdapter)cs).ObjectContext.Detach(city1);
EntityFramework 4:
cs.Detach(city1);
Il existe encore un autre moyen, au cas où vous n'auriez pas besoin du premier objet DBContext. Il suffit de l' envelopper avec l' aide de mots - clés:
la source
dbContext1.Entry(backgroundReport).State = System.Data.Entity.EntityState.Detached
'pour détacher et puis j'ai pu utiliserdbContext2.Entry(backgroundReport).State = System.Data.Entity.EntityState.Modified;
pour mettre à jour. A travaillé comme un rêveJ'ai eu le même problème mais mon problème avec la solution de @ Slauma (bien que géniale dans certains cas) est qu'elle recommande que je passe le contexte dans le service, ce qui implique que le contexte est disponible depuis mon contrôleur. Cela force également un couplage étroit entre mon contrôleur et les couches de service.
J'utilise Dependency Injection pour injecter les couches de service / référentiel dans le contrôleur et, en tant que tel, je n'ai pas accès au contexte du contrôleur.
Ma solution consistait à faire en sorte que les couches service / référentiel utilisent la même instance du contexte - Singleton.
Classe de singleton de contexte:
Référence: http://msdn.microsoft.com/en-us/library/ff650316.aspx
et http://csharpindepth.com/Articles/General/Singleton.aspx
Classe de référentiel:
D'autres solutions existent, comme instancier le contexte une fois et le transmettre aux constructeurs de vos couches de service / référentiel ou à une autre que j'ai lu sur l'implémentation du modèle d'unité de travail. Je suis sûr qu'il y en a plus ...
la source
Dans mon cas, j'utilisais ASP.NET Identity Framework. J'avais utilisé la
UserManager.FindByNameAsync
méthode intégrée pour récupérer uneApplicationUser
entité. J'ai ensuite essayé de référencer cette entité sur une entité nouvellement créée sur un autreDbContext
. Cela a abouti à l'exception que vous avez vue à l'origine.J'ai résolu ce problème en créant une nouvelle
ApplicationUser
entité avec uniquementId
laUserManager
méthode from et en référençant cette nouvelle entité.la source
J'ai eu le même problème et j'ai pu résoudre la création d'une nouvelle instance de l'objet que j'essayais de mettre à jour. Ensuite, j'ai passé cet objet à mon dépôt.
la source
Dans ce cas, il s'avère que l'erreur est très claire: Entity Framework ne peut pas suivre une entité en utilisant plusieurs instances de
IEntityChangeTracker
ou généralement plusieurs instances deDbContext
. Les solutions sont: utiliser une instance deDbContext
; accéder à toutes les entités nécessaires via un référentiel unique (en fonction d'une instance deDbContext
); ou désactivation du suivi pour toutes les entités accessibles via un référentiel autre que celui lançant cette exception particulière.Lorsque vous suivez une inversion de modèle de contrôle dans l'API Web .Net Core, je constate fréquemment que j'ai des contrôleurs avec des dépendances telles que:
et utilisation comme
Étant donné que les trois référentiels dépendent de différentes
DbContext
instances par requête, j'ai deux options pour éviter le problème et maintenir des référentiels séparés: modifiez l'injection du DbContext pour créer une nouvelle instance une seule fois par appel:ou, si l'entité enfant est utilisée en lecture seule, désactivez le suivi sur cette instance:
la source
Utilisez le même objet DBContext tout au long de la transaction.
la source
J'ai rencontré ce même problème après avoir implémenté IoC pour un projet (ASP.Net MVC EF6.2).
Habituellement, je initialiserais un contexte de données dans le constructeur d'un contrôleur et utiliserais le même contexte pour initialiser tous mes référentiels.
Cependant, l'utilisation d'IoC pour instancier les référentiels les a tous amenés à avoir des contextes séparés et j'ai commencé à recevoir cette erreur.
Pour l'instant, je suis revenu à la simple création de nouveaux référentiels avec un contexte commun tout en pensant à une meilleure façon.
la source
C'est ainsi que j'ai rencontré ce problème. Je dois d'abord enregistrer mon
Order
qui a besoin d'une référence à maApplicationUser
table:Le problème est que j'initialise un nouveau ApplicationDbContext pour enregistrer ma nouvelle
Order
entité:Donc, pour résoudre le problème, j'ai utilisé le même ApplicationDbContext au lieu d'utiliser le UserManager intégré d'ASP.NET MVC.
Au lieu de cela:
J'ai utilisé mon instance ApplicationDbContext existante:
la source
Source d'erreur:
J'espère que quelqu'un gagnera un temps précieux
la source