前言这个问题:我的问题是而不是,因为我直接在我的模型实体对象中设置了一个键属性(这是其他搜索结果中问题的原因)异常消息)。
我在我的应用程序中大量使用复合键,这是我当前数据库架构的简化版本(*asterisks*
中的关键字段):
Tenants( *TenantId*, ... )
Categories( *TenantId*, *CategoryId*, ... )
Documents( *TenantId*, *DocumentId*, CategoryId, ... )
Documents
表与Tenants
和Categories
都有FK关系,两者都使用相同的Documents.TenantId
列。 Documents.CategoryId
列NULL
为Tenant tenant = GetTenant( 123 );
Document doc = tenant.Documents.First();
Category newCategory = new Category();
newCategory.TenantId = 123;
dbContext.Categories.Add( newCategory );
doc.Category = newCategory; <-- exception is thrown on this line, without calling dbContext.SaveChanges() at all.
。
当我做这样的事情时,我得到了例外:
Category
我认为异常是因为在Document
实例上设置TenantId
会导致Documents -> Categories
属性由EF间接设置(因为它是{{1}的一部分FK协会。
解决方案是什么?
我可以通过创建新的Category
实体然后保存它们来获取IDENTITY
值,然后直接设置Document
属性来攻击它:
Tenant tenant = GetTenant( 123 );
Document doc = tenant.Documents.First();
Category newCategory = new Category();
newCategory.TenantId = 123;
dbContext.Categories.Add( newCategory );
dbContext.SaveChanges();
doc.CategoryId = newCategory.CategoryId
dbContext.SaveChanges();
但理想情况下,我希望只需一次调用SaveChanges()
并使用实体模型导航属性而不是标量属性属性。
答案 0 :(得分:0)
对于这个初始问题,我使用我发布到原始帖子的“替代方法更新”来处理它。
然而,对于不同的实体类型再次发生此问题(同样,使用外键中涉及的复合键)我注意到即使您在图中的任何实体上调用dbContext.Entry()
,EF也会抛出异常当新实体处于Added
状态时 - 如果您重新调用Entry()
甚至SaveChanges()
,它会不再次抛出异常,事实上尽管存在初始异常,它仍能正确保存新实体 - 所以我认为这可能只是EF中的一个错误。
这基本上就是我现在所拥有的:
Tenant tenant = GetTenant( 123 );
Document doc = tenant.Documents.First();
Category newCategory = new Category();
newCategory.TenantId = 123;
dbContext.Categories.Add( newCategory );
doc.CategoryId = newCategory.CategoryId
try {
dbContext.Entry( doc );
}
catch(InvalidOperationException) {
}
dbContext.SaveChanges();
这很丑陋,但有效 - 并且避免不得不两次致电SaveChanges
。