2015-10-21 83 views
0

我的課(和表)相關的對象:C#和EF 4 - 更新數據庫

class A { 
    public int Id {get; set;} 
    public string Name {get; set;} 

    public virtual C CField {get; set;} 
} 

class B { 
    public int Id {get; set;} 
    public string Name {get; set;} 
    public DateTime Date {get; set;} 

    public virtual C CField {get; set;} 
} 

class C { 
    public int Id {get; set;} 
    public string Name {get; set;} 
} 

class D { 
    public int Id {get; set;} 
    public string Title {get; set;} 

    public virtual A AField {get; set;} 
    public virtual B BField {get; set;} 
} 

我需要更新我的d對象。我使用依賴注入,所以我可以在控制器使用存儲庫:

A aObj = aService.GetAById(id); 
B bObj = bService.GetBByName(name); 
D dObj = new D() 
{ 
    Title = "MyTitle", 
    AField = aObj, 
    BField = bObj 
}; 
dService.Update(dObj); 

在每個分類儲存我只是創建上下文私有字段:

private MyContext db = new MyContext(); 

我用它在每一個方法,如:

var model = db.A.Where(x=>x.Id == id); 
return model; 

但它不能工作,因爲兩個類ABC class所以我仍然得到例外:當我調用dService.Update(dObj)(第二列表)時,一個實體對象不能被IEntityChangeTracker的多個實例引用。 我發現我應該在這樣每個repositroy脫離上下文中的每一個方法:

var model = db.A.Where(x=>x.Id == id); 
db.Entry(model).State = System.Data.Entity.EntityState.Detached; 
return model; 

例外是走了,但現在CField在aObjbObj總是空,不更新dObj.BField

我該如何解決這個問題,以及我做錯了什麼?我失去了幾天找出我應該做什麼:我甚至嘗試刪除存儲庫中的私有上下文字段,並在每個方法中使用using(var db = new MyContext()),但然後異常「一個實體對象不能被多個IEntityChangeTracker實例引用」返回。

回答

1

您不能在EF中混合來自不同上下文的實體。改用ids。

更新機型:

class A { 
    public int Id {get; set;} 
    public string Name {get; set;} 
    public int CFieldId {get; set;} 
    public virtual C CField {get; set;} 
} 

class B { 
    public int Id {get; set;} 
    public string Name {get; set;} 
    public DateTime Date {get; set;} 
    public int CFieldId {get; set;} 
    public virtual C CField {get; set;} 
} 

class C { 
    public int Id {get; set;} 
    public string Name {get; set;} 
} 

class D { 
    public int Id {get; set;} 
    public string Title {get; set;} 
    public int AFieldId {get; set;} 
    public int BFieldId {get; set;} 
    public virtual A AField {get; set;} 
    public virtual B BField {get; set;} 
} 

並在控制器:

A aObj = aService.GetAById(id); 
B bObj = bService.GetBByName(name); 
D dObj = new D() 
{ 
    Title = "MyTitle", 
    AFieldId = aObj.Id, 
    BFieldId = bObj.Id 
}; 
dService.Update(dObj); 
+0

您已經A'的'的標識,所以你不需要運行查詢'aService.GetAById(ID) ' – markpsmith

+0

@Szel:讓我親吻你! :D像魅力一樣工作,謝謝! –