2017-05-24 118 views
2

我有以下類別:DbSet.Attach試圖插入用於生成的標識列顯式值

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

public class MyContext : DbContext 
{ 
    public MyContext(DbContextOptions<MyContext> options) : base(options) { } 

    public DbSet<MyEntity> MyEntities { get; set; } 
} 

然後,在一個單獨的類我運行了以下內容:對的SaveChanges

var entity = new MyEntity(); 

myContext.MyEntities.Attach(entity).State = EntityState.Added; 

myContext.SaveChanges(); 

通話拋出異常:

當IDENTITY_INSERT設置爲O時,無法在表MyEntity中插入標識列的顯式值FF

此時我的模式完全按照慣例創建,Id列應該是自動生成的。這個問題似乎與我手動使用Attach和設置EntityState.Added有關。當我改爲使用Add這樣的:

myContext.MyEntities.Add(entity); 

它工作得很好。但是,我想使用Attach,因爲在我的真實場景中,MyEntity將具有數據庫中已存在的未跟蹤的子屬性。 Add自動將相關未跟蹤實體的狀態設置爲EntityState.Added,我不想將這些現有實體的狀態手動設置爲EntityState.Unchanged

我在這裏錯過了什麼?爲什麼EF試圖插入明確的身份值,即使在附加實體並將其狀態設置爲Added之後?

+0

這可能是一個EF核心執行錯過,但我會建議不要混合這些方法。試試'myContext.Entry(entity).State = EntityState.Added;'或'myContext.ChangeTracker.TrackGraph(entity,node => node.Entry.State =!node.Entry.IsKeySet?EntityState.Added:EntityState.Unchanged );' –

+0

這不是「這是你怎麼做」,但看看這個[答案](https://stackoverflow.com/questions/43721383/how-is-the-difference-between-add-or-delete- an-entity-from-the-dbset-and-from-lo/43878589#43878589)以獲取詳細信息。 'myContext.MyEntities.Local.Add(entity)'可以幫助你不添加子屬性。 – Smit

+0

@Smit實際上'Local.Add'似乎正是我想要的。相關的實體保持獨立,但添加的實體的ID引用正確地保存在「SaveChanges」的數據庫中。你是否知道在這種情況下只需使用Local.Add就可以解決一些重大問題?我可以看到,因爲相關的實體保持分離狀態,它們在'SaveChanges'之後的DbContext中不可用,但在我的情況中很好。 – codestothestars

回答

1

這是EF中的設計行爲。 如果調用Add(),則意味着該對象不存在於數據庫中,因此將爲該實體生成一個密鑰。 如果調用Attach(),則意味着它存在於數據庫中,因此即使將狀態設置爲稍後添加,也不會執行密鑰生成。

+0

謝謝。你知道有什麼方法可以告訴EF在Attach()後生成一個ID,或者__not__標記爲Add()上添加的相關實體?相關實體的標記爲「正在添加」是我試圖避免的,所以我不必將它們手動設置爲「未更改」。 – codestothestars

+0

@ X-Malleus我知道的唯一方法就是你提到的那種:將狀態設置爲Unchanged或Detached。我知道在那裏有幾個第三方庫可以解決這個問題,但這對我來說從來就不是關鍵問題。 –

相關問題