使用GraphDiff更新多对多关系会导致错误

时间:2014-09-17 08:18:53

标签: c# entity-framework ef-code-first many-to-many graphdiff

我在我的应用程序中使用EF code first 6.1 .NET 4并在我的模型中使用了以下类(我剪切了其他不相关的图表部分。例如Permission有其他导航): enter image description here

我的业务逻辑适用于分离的实体,所以我使用RefactorThis.GraphDiff 2.0.1.0来执行更新。 我想要更新applicationUserInApplication对象,因此我从数据库中获取现有applicationUserInApplication及其SecurityRole s并将其作为View-Model返回,然后将其更新并将其映射回applicationUserInApplication使用Automapper {在更新操作中,我只更改了SecurityRoles的{​​{1}}集合,之前保存了这些applicationUserInApplication,我只选择了它们,所以我定义了以下配置:

SecurityRole

并定义了_dbContext.UpdateGraph(appUserInApplication, map => map .OwnedCollection(t => t.SecurityRoles, with=> with.AssociatedCollection(t=>t.Permissions) .AssociatedEntity(t => t.ApplicationDescriptor)) .AssociatedEntity(t=>t.ApplicationDescriptor) .AssociatedEntity(t=>t.AppUser) .AssociatedEntity(t=>t.UserProfile)); 类中AppUserInApplication的以下映射:

AppUserInApplication_Mapping

在调用this.HasRequired(t => t.AppUser).WithMany(t => t.AppUserInApplications).HasForeignKey(d => d.AppUserId); this.HasRequired(t => t.Applicationdescriptor).WithMany(t => t.AppUserInApplications).HasForeignKey(d => d.ApplicationId); this.HasMany(t => t.SecurityRoles).WithMany(t => t.AppUserInApplications) .Map(m => { m.ToTable("AppUserInApplicationSecurityRole"); m.MapLeftKey("AppUserInApplications_Id"); m.MapRightKey("SecurityRoles_Id"); }); this.HasRequired(t => t.UserProfile).WithMany().HasForeignKey(t=>t.UserProfileId); 之后,当我致电UpdateGraph()时,我收到以下错误:

  

EntityFramework.dll中出现未处理的“System.InvalidOperationException”类型异常   附加信息:操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

[更新]

我也尝试过映射

_dbContext.SaveChange();

但是我得到同样的错误。

有谁知道问题出在哪里?

[更新]

我上传了我的模型的简化版本,您可以从https://www.dropbox.com/s/i9dvrb6ebd5wo7h/GraphdiffTest.rar?dl=0

获取

2 个答案:

答案 0 :(得分:3)

该异常意味着Entity Framework正在抱怨您已根据需要映射但未设置的导航属性(它们为空)。在调试示例代码之后,除了安全角色之外,所有导航属性都是如此。

如果你改变你的代码:

working code

导航属性已设置,一切正常。

答案 1 :(得分:0)

我查看了你的代码,我认为问题出在你的映射中。 AppUserInApplication表与表SecurityRoles具有多对多关系,并且在您的映射中使用“OwnedCollection” - 应该在一对多或一对一关系中使用,请尝试使用AssociatedCollection。 / p>

  _dbContext.UpdateGraph(appUserInApplication, map => map
            .AssociatedCollection(t => t.SecurityRoles, with=> (....)