2013-12-12 29 views
-1

我保存與Section有1-M關係的對象(FeatureType)時遇到了一些問題。用EF保存一個項目與現有的兒童

public class FeatureType 
    { 
     public int Id { get; set; } 

     public string Name { get; set; } 

     [ForeignKey("SectionId")] 
     public Section Section { get; set; } 

     public virtual List<ItemType> ItemTypes { set; get; } 
    } 

    public class Section 
    { 
     public int Id { get; set; } 

     public string Name { get; set; } 

     public int Order { get; set; } 

     public virtual List<FeatureType> Features { get; set; } 
    } 

如果itemTypes的新我沒有問題,並且插入正確完成。

但是如果我想補充一些現有ItemTypes即時得到這個錯誤:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

我一直在閱讀關於這個問題,但我還沒有找到一種方法來解決它,這可能是因爲如何了設計我的應用。

從我的ViewModel到我的模型,即時得到的部分ID,並從我SectionRepository獲得部分對象,因爲這

Whem IM mappinig:

private Section GetSection() 
     { 
      var section = _sectionRepository.GetSection(SectionId); 
      return section; 
     } 

這是什麼給我的問題,因爲部分現在已經由具有自己的上下文的SectionRepository進行跟蹤。

我該如何解決這個問題?我試圖用現有的ID創建一個新的部分,但它只是創建一個空對象。

private Section GetSection() 
      { 
       var section = new Section{Id=SectionId}; 
       return section; 
      } 

UPDATE

要保存我的實體,我只是用:

_repository.Create(featureType.ToModel()); 

    public FeatureType ToModel() 
     { 
      var ft = new FeatureType 
         { 
          Name = Name, 
          ControlType = (ControlType)ControlType, 
          Order = Order, 
          Required = Required, 
          RequiredText = RequiredText, 
          ItemTypes = GetItemTypes().ToList(), 
          Section = GetSection(), 
         }; 

      return ft; 
     } 

更新2:這是我有我的倉庫,我不希望在管理任何EF我控制器,但有某種存儲庫或服務。

public class EFBaseRepository 
    { 
     protected MyContext Db = new MyContext(); 

     public void Dispose(bool disposing) 
     { 
      Db.Dispose(); 
     } 
    } 

public class EFFeatureTypeRepository : EFBaseRepository, IFeatureTypeRepository 
    { 
     public IQueryable<FeatureType> GetFeatureTypes 
     { 
      get { return Db.FeatureTypes.Include("Section").Include("ItemTypes"); } 
     } 

public Message Create(FeatureType feature) 
     { 
      try 
      { 
       Db.FeatureTypes.Add(feature); 
       Db.SaveChanges(); 
       return new Message(); 
      } 
      catch (Exception e) 
      { 
       throw; 
       // return new Message(e, string.Format("Error Creating {0}", feature.GetType())); 
      } 
     } 

//..Other Methods 
} 
+1

檢查此請http://stackoverflow.com/questions/14307838/entity-framework-adding-existing-child-poco-to-new-parent-poco-creates-new-chi – LINQ2Vodka

回答

1

你說SectionRepository有它自己的上下文。這會導致你的問題。存儲庫應該共享一個上下文。上下文是工作單元和存儲庫模式的組合。您需要將兩種模式分開:

How to migrate towards unit-of-work and repository pattern

編輯

您可以避免通過實現自己的單位工作模式具有在控制器中DbContext

public interface IUnitOfWork : IDisposable 
{ 
    ISectionRepository SectionRepository {get;} 
    //etc 

    int Save(); 
} 

然後在你的控制器:

public ActionResult Create(FeatureTypeCreate featureType) 
{ 
    _Uow.SectionRepository.Create(featureType.ToModel()); 
    _Uow.Save(); //Saving is the responsibility of the Unit Of Work 
       //not the Repository 
} 

更多的參考資料:

Implementing the Repository and Unit of Work

Repository and Unit of Work in Entity Framework

John Papa's original source code

+0

感謝科林,這看起來像我所需要的,我會仔細閱讀,並嘗試看看我能否實施它。 –

+0

有沒有辦法避免在我的控制器中調用上下文?這是我試圖用我的存儲庫做的。 –

+0

請檢查我更新的問題,看看我有我的知識庫,看看我們如何解決它。 –

0

簡單地說,錯誤你得到的實體從您DbContext的不同實例,比他們現在正在努力保存返回手段。確保你沒有像在存儲庫中使用兩個不同的using這樣的東西,並且你的存儲庫總是使用每個實例相同的DbContext

+0

請檢查我更新的問題,看看如何我有我的知識庫,看看我們如何解決它,我明白這是問題,但我不知道如何解決它。 –