c# 一個實體物件不能被多個ientitychangetracker的執行個體參考 - 實體對像不能被IEntityChangeTracker的多個實例引用。 同時在實體框架4.1中將相關對象添加到實體




object cannot (9)

我正在嘗試保存員工詳細信息,該信息與城市有關。 但每次我嘗試保存我的聯繫人,這是驗證我得到異常“ADO.Net實體框架一個實體對像不能被多個IEntityChangeTracker實例引用”

我讀過這麼多的文章,但仍然沒有得到確切的想法做什麼...我保存按鈕點擊代碼如下

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);
    }

員工服務代碼

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";
        }

Answers

這是一個舊線程,但我更喜歡的另一個解決方案是更新cityId,而不是將空洞模型City分配給Employee ...來執行該操作Employee應該看起來像這樣:

public class Employee{
...
public int? CityId; //The ? is for allow City nullable
public virtual City City;
}

然後它足夠分配:

e1.CityId=city1.ID;

在整個事務中使用相同的DBContext對象。


就我而言,我使用的是ASP.NET Identity Framework。 我使用內置的UserManager.FindByNameAsync方法來檢索ApplicationUser實體。 然後我嘗試在不同的DbContext上新創建的實體上引用此實體。 這導致你最初看到的例外。

我通過創建一個新的ApplicationUser實體來解決這個問題,只需使用UserManager方法中的Id並引用新的實體。


錯誤來源:

ApplicationUser user = await UserManager.FindByIdAsync(User.Identity.Name);
ApplicationDbContext db = new ApplicationDbContent();
db.Users.Uploads.Add(new MyUpload{FileName="newfile.png"});
await db.SavechangesAsync();/ZZZZZZZ

希望有人節省一些寶貴的時間


另外注射和更糟糕的單身人士,你可以在Add之前調用Detach方法。

EntityFramework 6: ((IObjectContextAdapter)cs).ObjectContext.Detach(city1);

EntityFramework 4: cs.Detach(city1);

還有另外一種方法,以防你不需要第一個DBContext對象。 只需使用關鍵字包裝它:

Payroll.Entities.City city1;
using (CityService cs = new CityService())
{
  city1 = cs.SelectCity(Convert.ToInt64(cmbCity.SelectedItem.Value));
}

我有同樣的問題,我可以解決一個新的實例,我試圖更新的對象。 然後我把這個東西傳給了我的回憶錄。


重現步驟可以簡化為:

var contextOne = new EntityContext();
var contextTwo = new EntityContext();

var user = contexOne.Users.FirstOrDefault();

var group = new Group();
group.User = user;

contextTwo.Groups.Add(group);
contextTwo.SaveChanges();

沒有錯誤的代碼:

var context = new EntityContext();

var user = context.Users.FirstOrDefault();

var group = new Group();
group.User = user; // Be careful when you set entity properties. 
// Be sure that all objects came from the same context

context.Groups.Add(group);
context.SaveChanges();

因為這兩條線......

EmployeeService es = new EmployeeService();
CityService cs = new CityService();

...不要在構造函數中使用參數,我想你會在類中創建一個上下文。 當你加載city1 ...

Payroll.Entities.City city1 = cs.SelectCity(...);

...您將city1附加到city1中的上下文。 稍後,您將city1添加為新Employee e1的引用,並將包含對city1此引用的 e1添加city1中的上下文中。 因此,您將city1附加到兩個不同的上下文,這是異常抱怨的內容。

您可以通過在服務類之外創建一個上下文並在兩個服務中註入和使用它來解決此問題:

EmployeeService es = new EmployeeService(context);
CityService cs = new CityService(context); // same context instance

您的服務類看起來有點像只負責一個實體類型的存儲庫。 在這種情況下,當您為服務使用單獨的上下文時,只要涉及到實體之間的關係,就會遇到麻煩。

您還可以創建一個服務,負責一組密切相關的實體,如EmployeeCityService (具有單個上下文),並將Button1_Click方法中的整個操作委託給此服務的一個方法。






c# asp.net entity-framework ado.net foreign-keys