2015-07-12 111 views
0

我在我的項目中遇到以下異常;確保顯式設置的主鍵值是唯一的

類型的異常「System.InvalidOperationException」發生在 EntityFramework.dll但在用戶代碼中沒有處理

其他信息:保存或接受更改失敗類型的「,因爲 多於一個實體MyProject的.Data.Poco.MyProjectCountry'具有相同的主鍵值 。確保明確設置的主鍵值 是唯一的。確保數據庫生成的主鍵在數據庫和實體框架模型中正確配置爲 。使用 實體設計器進行數據庫優先/模型優先配置。使用 「HasDatabaseGeneratedOption」一口流利的API或 'DatabaseGeneratedAttribute' 的代碼首先配置

using (MyProjectDataContext context = new MyProjectDataContext()) 
       { 
        MyProjectItemTag existingItemTag = (from p in context.ItemTags.Include(p => p.MyProjectGenre).Include(p => p.MyProjectCountry) 
                where p.MyProjectUser.UserId == ItemTag.MyProjectUser.UserId && 
                  p.MyProjectItem.ItemId == MyProjectItem.ItemId 
                select p).FirstOrDefault(); 


        // new tag 
        if (existingItemTag == null) 
        { 
         existingItemTag = ItemTag; 
         existingItemTag.MyProjectItem.ItemId = MyProjectItem.ItemId; 
        } 
        // existing tag 
        else 
        { 
         existingItemTag.MyProjectItem = new MyProjectItem { ItemId = MyProjectItem.ItemId }; 
         existingItemTag.MyProjectUser = new MyProjectUser { UserId = ItemTag.MyProjectUser.UserId }; 
        } 
        // updates 
        existingItemTag.MyProjectCountry = MyProjectCountry; 
        if (MyProjectCountry != null) 
         existingItemTag.MyProjectCountry = new MyProjectCountry() 
         { 
          MyProjectCountryId = MyProjectCountry.MyProjectCountryId 
         }; 
        existingItemTag.MyProjectGenre = MyProjectGenre; 
        context.Entry(existingItemTag.MyProjectItem).State = EntityState.Unchanged; 
        context.Entry(existingItemTag.MyProjectUser).State = EntityState.Unchanged; 
        context.Entry(existingItemTag.MyProjectCountry).State = EntityState.Unchanged; 
        context.Entry(existingItemTag.MyProjectGenre).State = EntityState.Unchanged; 
        if (existingItemTag.MyProjectCountry != null) 
        { 
         context.Entry(existingItemTag.MyProjectCountry).State = EntityState.Unchanged; 
        } 
        // db 
        context.ItemTags.AddOrUpdate(existingItemTag); 
        context.SaveChanges(); 
        return existingItemTag.ItemTagId; 
       } 
      } 

錯誤發生在下面一行。

context.Entry(existingItemTag.MyProjectCountry).State = EntityState.Unchanged; 

我的班級;

public class MyProjectItemTag 
    { 
     public int ItemTagId { get; set; } 
     public MyProjectUser MyProjectUser { get; set; } 
     public MyProjectItem MyProjectItem { get; set; } 
     public MyProjectCountry MyProjectCountry { get; set; } 
     public MyProjectGenre MyProjectGenre { get; set; } 
     public MyProjectMood MyProjectMood { get; set; } 
     public MyProjectItemTag() 
     { 

     } 
     public MyProjectItemTag(string userId, string providerContentId) 
     { 
      MyProjectUser = new MyProjectUser 
      { 
       UserId = userId 
      }; 
      MyProjectItem = new MyProjectItem 
      { 
       ProviderContentId = providerContentId 
      }; 

} }

我的配置;

public class MyProjectItemTagConfiguration : EntityTypeConfiguration<MyProjectItemTag> 
    { 
     public MyProjectItemTagConfiguration() 
     { 
      ToTable("MyProjectItemTags"); 
      HasKey(p => p.ItemTagId); 
      HasRequired(p => p.MyProjectUser); 
      HasRequired(p => p.MyProjectItem); 
      HasOptional(p => p.MyProjectCountry); 
     } 
    } 

我在這裏失蹤了什麼?

+0

當'existingItemTag'是新的時候,你重新插入一個正在退出的'Country'。 –

+0

我缺少的是== nulll的情況下,你做... existingItemTag = ItemTag;什麼是ItemTag?這是一個財產嗎?它是什麼?我認爲這個問題的答案是回答你的問題的關鍵。 – Mick

回答

2

這是你真正需要尋找:

其他信息:保存或接受更改失敗,因爲類型的多個實體「MyProject.Data.Poco.MyProjectCountry」具有相同的主鍵值。

以下代碼可能不一定會填充MyProjectCountry

MyProjectItemTag existingItemTag = 
    (from p in context.ItemTags 
    .Include(p => p.MyProjectGenre) 
    .Include(p => p.MyProjectCountry) 
    where p.MyProjectUser.UserId == ItemTag.MyProjectUser.UserId 
    && p.MyProjectItem.ItemId == MyProjectItem.ItemId 
    select p).FirstOrDefault(); 

所以將它設置爲某個變量你還沒有給我們太多的任何上下文...

existingItemTag.MyProjectCountry = MyProjectCountry; 

我認爲它不爲空,所以你改變它的ID是一個巨人Code Smell ...

(爲什麼分配呢?畢竟它已經分配..)

if (MyProjectCountry != null) 
    existingItemTag.MyProjectCountry = new MyProjectCountry() 
    { 
    MyProjectCountryId = MyProjectCountry.MyProjectCountryId 
    }; 

然後你牛逼它的EF沒有改變?另一個代碼嗅覺。

context.Entry(existingItemTag.MyProjectCountry).State = EntityState.Unchanged; 

所以這告訴我的是,語境已經下載這個實體到其對象緩存,但你分配一個是不是一個在緩存中,所以當我試圖添加到緩存中,有是重複的。

+0

這是真的,上下文具有相同對象的重複緩存,因此失敗。 –