2009-11-14 13 views
1

當我運行下面的代碼:「嘗試附加或添加一個不是新的實體,可能是從另一個DataContext加載的,不支持。」

public ActionResult Complete() 
     { 
      try 
      { 
       VeriTabanDataContext db = new VeriTabanDataContext(); 
       db.Persons.InsertOnSubmit(_person); 
       db.SubmitChanges(); 
       return View(_person); 
      } 
      catch (Exception ex) 
      { 
       return RedirectToAction("Error", ex); 
      } 
     } 

我得到以下異常,上的SubmitChanges();

"An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported." 
  • 這裏的「_person」對象從會議所作,是一個良好的信譽。注意:_person是多步向導的結果,這是我將新Person對象添加到數據庫的地方。
  • 我的人表有9個關係,它不是我可以爲他們每個人添加版本列,如一些怪傑建議的
  • 我已經調查了這個問題很多,並花費了2天對它仍然couldn解決不了。其他建議的一些解決方法不能解決我的問題,而其他解決方案似乎只是骯髒的解決方法。考慮到Person類有很多關係,並且向表中添加列也不行,專家是否有解決此問題的良好解決方案?
  • 我還想指出,我試過使用'db.Persons.Attach(_person)'並設置db.DeferredLoadingEnabled = false;這一次我沒有得到任何異常,但數據不會保存到DB

回答

2

我創建了一個名爲的ApplicationController類它來自Controller。然後我讓我的所有控制器類都從這個派生。該ApplicationController中類有它創建我的存儲庫的一個新實例(或DataContext的在您的實例),這是整個應用程序使用的constrcutor:

 public class ApplicationController : Controller 
    { 
      private VeriTabanDataContext _datacontext; 

      public ApplicationController() : this(new VeriTabanDataContext()) 
      { 
      } 

      public ApplicationController(VeriTabanDataContext datacontext) 
      { 
       _datacontext = datacontext; 
      } 

      Public VeriTabanDataContext DataContext 
      { 
       get { return _datacontext; } 
      } 
    } 

然後你就可以在所有的控制器使用

public class MyController : ApplicationController 
{ 
    public ActionResult Complete()   
    {    
      DataContext.Persons.InsertOnSubmit(_person);    
      DataContext.SubmitChanges();     
      return View(_person);    
    } 
} 

不是我用VS電腦上安裝的所以沒有測試此代碼的那一刻....

希望這樣可以解決問題 - 馬克

+0

我還沒有嘗試過,但是這將解決問題,如果我的對象是從上下文中取出並試圖插入到另一個上下文中。但是我的對象是新創建的,並沒有被任何背景跟蹤。所以我懷疑這是行不通的。我只想在嘗試之前說出我的意見,如果我的想法被證明是錯誤的,那麼稍後再嘗試。 – 2009-11-14 10:28:31

+0

應該工作,因爲您將只有一個datacontext實例,目前看起來您正在每個控制器操作中創建多個實例。 – Mark 2009-11-14 10:55:15

+0

這解決了我的問題。謝謝。 – 2009-11-16 10:20:08

1

你能做到以下幾點:

var foundPerson = db.Person.FirstOrDefault(p => p.Id == _person.Id); 

if(foundPerson == null) 
{ 
    db.InsertOnSubmit(_person); 
}else{ 
    Mapper.Map(_person,foundPerson); 
} 

db.SubmitChanges(); 
return View(_person); 

當我用AutoMapper映射從一個實體到另一個。要做到這一點的參考AutoMapper添加到您的項目,並在啓動時的代碼爲應用程序,您需要配置映射,對於上述工作,你將需要:

Mapper.CreateMap<Person, Person>().ForMember(src => src.Id, opt => opt.Ignore()); 
+0

'foundPerson.Name = _p erson.Name'不適用於我,因爲這樣我必須複製30多個字段。此外,如果依賴計數的奇爾德物體,那麼我將不得不爲100多個場進行這種分配。所以這個解決方案是不可接受的,除非有更簡單的方法來更新'foundPerson'。謝謝你的回答。 – 2009-11-14 10:22:39

+0

更新爲使用AutoMapper – bobwah 2009-11-14 11:08:43

相關問題