"属性$ propertyName是对象的关键信息的一部分,不能修改。"在具有共享组合键的导航属性上

时间:2016-08-01 11:28:43

标签: entity-framework

前言这个问题:我的问题是而不是,因为我直接在我的模型实体对象中设置了一个键属性(这是其他搜索结果中问题的原因)异常消息)。

我在我的应用程序中大量使用复合键,这是我当前数据库架构的简化版本(*asterisks*中的关键字段):

Tenants( *TenantId*, ... )
Categories( *TenantId*, *CategoryId*, ... )
Documents( *TenantId*, *DocumentId*, CategoryId, ... )

Documents表与TenantsCategories都有FK关系,两者都使用相同的Documents.TenantId列。 Documents.CategoryIdNULLTenant 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()并使用实体模型导航属性而不是标量属性属性。

1 个答案:

答案 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