2017-06-12 43 views
2

我正在使用AutoMapper並嘗試使用AutoMapper.Collection.EntityFramework,特別是Persist<T>方法。AutoMapper.Collection.EntityFramework在Persist.InsertOrUpdate後導致InvalidOperationException

我的「源」是一個相當大的對象圖,已被轉換(由AutoMapper)轉換爲一些EntityFramework實體。父實體稱爲Log

在我的實驗測試,我做了以下內容:

var mapper = collectionConfig.CreateMapper(); 
var persistence = dbContext.Logs.Persist(mapper); 
var testLog = logs.First(); // "logs" is the output of an AutoMapper.Map of a collection. 
persistence.InsertOrUpdate<Log>(testLog); 

Assert.IsTrue(dbContext.ChangeTracker.HasChanges()); 

什麼情況是在ChangeTracker.HasChanges調用異常:

System.InvalidOperationException:該物業 'ID' 是的一部分 對象的關鍵信息,不能修改。

堆棧跟蹤爲:

System.Data.Entity.Core.Objects.EntityEntry.DetectChangesInProperty(的Int32 序,布爾detectOnlyComplexProperties,布爾detectOnly)
在 System.Data.Entity的在在 System.Data.Entity.Core.Objects.ObjectStateManager.DetectChangesInScalarAndComplexProperties(IList`1 條目).Core.Objects.EntityEntry.DetectChangesInProperties(布爾 detectOnlyComplexProperties) System.Data.Entity.Core.Objects.ObjectStateManager.DetectChanges()
在System.Data.Entity.Core.Objects.ObjectContext.DetectChanges()在 System.Data.Entity.Internal.InternalContext.DetectChanges(布爾 力)在 System.Data.Entity.Infrastructure.DbChangeTracker.HasChanges()

這是一個相當知名的和證據充分的情況例外:當你有一個現有的EntityFramework實體對象,並試圖改變它發生其主要關鍵屬性字段之一的值。

但我不這樣做的任何地方。

我從來沒有在我的代碼設置的Id值。 (爲Id屬性的值來自其他地方,由AutoMapper創建Log對象的名單時因爲我有理由相信,對於testLog對象的條目確實已經存在於數據庫中的數據的性質。 )

我已經能夠,拯救整個集合Log項,通過創建AutoMapper的數據庫,通過EF,所以我不認爲我的Log實體或對象圖有問題。我認爲這是AutoMapper.Collection.EntityFramework某種程度上在做的事情。

我曾嘗試Persist方法有不同的,更簡單的實體,與衆多較少的子實體,並沒有這個問題。但是我甚至無法從這個錯誤中知道圖中的哪個對象具有所謂的Id值:此對象圖中的一半對象具有名爲Id的主鍵。

我可以確認實際testLog.Id沒有被InsertOrUpdate更改。但我試圖檢查Entry<Log>testLog甚至看dbContext.Logs.Local都會導致拋出相同的異常。

所以:任何人有一個想法,爲什麼發生這種情況?

回答

0

感謝的AutoMapper.CollectionTyler Carlson,我有一個答案。

persistence.InsertOrUpdate<Log>(testLog); 

問題從testLog朵朵已被Log類型,這是我使用的EntityFramework相同類型的。正如泰勒所說:

Automapper不支持映射本身,因爲它會導致這麼多 問題。 [...]
您應該做的是將dto傳遞給persist調用,而不是它映射到的實體。那個 映射將在InsertOrUpdate調用中發生。

我們還發現,如果你的EntityDto對象共享一個共同的基類,和基類包含鍵字段的定義,這也將發生。

在我的情況,我的 EntityDto含有相同領域的95%,從一個共同的基類派生

所以,我不得不採取Id屬性,它是主鍵列的基類,並把它定義分別在兩個班。這確保了,儘管這些房產具有相同的名稱,但它們在任何意義上都不是與Reflection觀點相同的房產。

如果您想了解詳細信息,討論是在這裏:AutoMapper.Collection Issue 40

相關問題