2

我知道這似乎是重複的條目,但我衝我與問題相關的所有帖子,我無法找到解決方案。我一個星期左右就陷入這個問題。也許我做了一些設計問題或者我不知道。問題是我無法更新導航屬性,我嘗試了幾個選項,每當我得到一個不同的錯誤或重複。好吧,這裏的情況:無法更新外鍵引用(導航屬性)

我有一個對象 「名單」
INT ID
字符串名稱
INT SendType
分類類別//這些導航屬性
產品產品//這些都是導航property

類別和產品不知道與List的關係。我使用CTP5 DbContext生成器模板生成的POCO類,並使用每個實體的存儲庫。在每個存儲庫中都有一個對dbcontext的引用。

這是控制器:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Edit(int id, List list) 
    { 
     if (!ModelState.IsValid) 
      return View(list); 

     List originalList = this._listRepository.Get(id); 
     TryUpdateModel(originalList, "List", new string[] { "Name", "SendType"}); 
     //Here's I tried to update manually like this 
     if (list.category.id != originalList.category.id) 
     { 
      Category category = this._categoryRepository.GetNoTracking(list.category.id); 
      originalList.Category = category; 
     } 
     if (list.product.id != originalList.product.id) 
     { 
      Product product = this._productRepository.GetNoTracking(list.product.id); 
      originalList.Product = product; 
     } 
     this._listRepository.Save(); //Here's I call only the SubmitChanges() 
     return RedirectToAction("Index");        
    } 

如果我嘗試直接收到錯誤

的實體類型「DbEntityEntry」是不是該機型爲當前上下文

的一部分

因爲我修改實體類別或產品的狀態(它們來自另一個上下文)

如果我提交的修改,不修改的關聯,我收到錯誤

「IDCategory」是一個關鍵的參考,不能更新

等等......任何建議將不勝感激,如果我錯了,我也可以修改viewmodel。我沒有想法!由於

UPDATE

//This is in List Repository 
    public override void Save() 
    {   
     checkReferencies(); 
     db.SaveChanges();    
    } 

    private void checkReferencies() 
    {   
     foreach (var entry in db.ChangeTracker.Entries() 
           .Where(e => e.State == EntityState.Modified || e.State == EntityState.Added)) 
     { 
      if (ObjectContext.GetObjectType(entry.Entity.GetType()).Name.Equals("List")) 
      { 
       /*In this case I tried to update my object directly with the object that comes form the form 
       if (entry.CurrentValues.GetValue<int>("IDList").ToString() != "0") 
       { 
        db.Entry(entry.Entity).State = EntityState.Modified; 
       } */     
       if (((List)entry.Entity).Product != null) 
       { 
        db.Entry(((List)entry.Entity).Product).State = EntityState.Unchanged; 
       } 
       if (((List)entry.Entity).Category != null) 
       { 
        db.Entry(((List)entry.Entity).Category).State = EntityState.Unchanged; 
       } 
      } 
      else if (ObjectContext.GetObjectType(entry.Entity.GetType()).Name.Equals("Product") 
        || ObjectContext.GetObjectType(entry.Entity.GetType()).Name.Equals("Category")) 
      { 
       //here I attach the entry that I added 
       db.Category.Attach((Category)db.Entry(entry).Entity.Entity); 

      } 
     } 
    } 

    //This is in categoryRepository 
    public Category GetNoTracking(int id) 
    {    
     return db.Category.AsNoTracking().Single(l => l.IDCategory == id); 
    } 

    //This is in productRepository 
    public Product GetNoTracking(int id) 
    {    
     return db.Product.AsNoTracking().Single(l => l.IDProduct == id); 
    } 

    //This is my DbContext 
    namespace BusinessManagerEmail.Models 
    { 
     using System; 
     using System.Data.Entity; 

     public partial class DBMailMarketingEntities : DbContext 
     { 
      public DBMailMarketingEntities() 
      : base("name=DBMailMarketingEntities") 
      { 
      } 

      public DbSet<Category> Category { get; set; } 
      public DbSet<Customer> Customer { get; set; } 
      public DbSet<Subscription> Subscription { get; set; } 
      public DbSet<List> List { get; set; } 
      public DbSet<Product> Product { get; set; } 
     } 
    } 

這是所有的代碼參與。謝謝!

+0

爲什麼不在庫之間共享上下文? – 2011-03-14 13:02:44

+0

因爲這是我在MVC中的第一個項目,所以我遵循了NerdDinner的指導原則。我的下一步是添加一個包裝上下文的UnitOfWork。但現在我必須按照我發佈的方式來做:(顯然不是我的意願)! – stuzzo 2011-03-14 13:09:06

+0

「因爲我修改了實體類別或產品的狀態」:你在做什麼以及在哪個狀態下修改?如前所述Ladislav,如果你在「_listRepository」和「_listCategory」中有不同的上下文,那麼'category'沒有附加到_listRepository的上下文或者是一些重要的代碼片段丟失? – Slauma 2011-03-14 14:59:17

回答

0

刪除checkReferencies因爲:

  • List在你的例子沒有被修改,從而該方法的第一部分將不被執行。
  • Product不能轉換爲Category並附加到DbSet。它會拋出異常。
  • Category已經加入Addes狀態(這是錯誤的,因爲它會再次插入類別)。再次連接實體會拋出異常。

只需連接兩個CategoryProductlistRepository環境下,你在List設置在他們面前。

或者更好地完全重寫你的代碼,並在不同的存儲庫中共享上下文。

+0

感謝您的所有建議!我試圖修改它,我希望能夠解決它!我很確定我需要你的幫助:P! – stuzzo 2011-03-15 14:26:16

+0

你是完全正確的!我刪除了所有的代碼,然後用你的建議重寫它!謝謝你的幫助!對不起,如果我發佈了一個可怕的代碼! – stuzzo 2011-03-16 13:25:44