使用modelbuilder创建复合键时

时间:2015-04-30 19:53:25

标签: c# asp.net-mvc entity-framework dbcontext

我正在使用EF 6并尝试绕过此错误消息:

  

操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

我在dbcontext中使用modelbuilder阅读有关此解决方案的内容,以创建似乎可以解决此问题的复合键:https://lostechies.com/jimmybogard/2014/05/08/missing-ef-feature-workarounds-cascade-delete-orphans/(不是帖子本身,第一条评论)

无论如何,生活很美好我有一个有各种孩子的父模型,一切都像梦一样,直到我试图用一个本身有孩子的子对象来实现它。这是我的模型的缩写版本:

public class StateYear
{
    public long stateYearId { get; set; }
    public string year { get; set; }
    ...

    public virtual ICollection<Plan> Plans { get; set; }
    public virtual ICollection<ReportAssignment> ReportAssignments { get; set; }
}

public class Plan
{
    public long planId { get; set; }
    public long stateYearId { get; set; }
    ...

    public virtual StateYear StateYear { get; set; }
}

public class ReportAssignment
{
    public long reportAssignmentId { get; set; }
    public long stateYearId { get; set; }
    ...

    public virtual StateYear StateYear { get; set; }
    public virtual ICollection<McoPihpAssignment> McoPihpAssignments { get; set; }
}

public class McoPihpAssignment
{
    public long mcoPihpAssignmentId { get; set; }
    public long reportAssignmentId { get; set; }
    ...

    public virtual ReportAssignment ReportAssignment { get; set; }
}

我在我的DbContext中实现了模型构建器解决方案,如下所示:

        modelBuilder.Entity<Plan>()
            .HasKey(a => new { a.planId, a.stateYearId});
        modelBuilder.Entity<Plan>()
            .Property(a => a.planId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        modelBuilder.Entity<ReportAssignment>()
            .HasKey(a => new { a.reportAssignmentId, a.stateYearId });
        modelBuilder.Entity<ReportAssignment>()
            .Property(a => a.reportAssignmentId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        modelBuilder.Entity<McoPihpAssignment>()
            .HasKey(a => new { a.mcoPihpAssignmentId, a.reportAssignmentId });
        modelBuilder.Entity<McoPihpAssignment>()
            .Property(a => a.mcoPihpAssignmentId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

但是当我尝试检索StateYear记录时,我收到以下错误消息:

  Message=Invalid column name 'ReportAssignment_reportAssignmentId'. 
  Invalid column name 'ReportAssignment_stateYearId'.

我知道这是来自ReportAssignment上的模型构建器,我在其中创建了复合键,因为当我评论它的工作原理时,或者当我在ReportAssignment模型上注释掉McoPihpAssignment Collection时,它也可以工作。我只是没有找到解决这个错误的方法,我也不确定为什么这个错误现在出现,当它适用于Plan时。任何帮助或建议将不胜感激!谢谢!

更新所以我发现它适用于Plan,因为Plan没有任何正在寻找其复合键的子项。所以看起来McoPihpAssignment正在ReportAssignment上寻找复合键属性reportAssignmentId和stateYearId。我找到了EF生成的SQL代码,它调用了这些触发错误的属性:

SELECT 
[Project1].[stateId] AS [stateId], 
[Project1].[year] AS [year], 
[Project1].[reportAssignmentId] AS [reportAssignmentId], 
[Project1].[stateYearId1] AS [stateYearId1], 
[Project1].[mcoPihpAssignmentId] AS [mcoPihpAssignmentId], 
[Project1].[reportAssignmentId1] AS [reportAssignmentId1], 
[Project1].[ReportAssignment_reportAssignmentId] AS [ReportAssignment_reportAssignmentId], 
[Project1].[ReportAssignment_stateYearId] AS [ReportAssignment_stateYearId]
FROM ( ... )  AS [Project1]

无论如何,我认为我的新问题是,有没有办法在McoPihpAssignment或ReportAssignment模型上添加或修饰属性,以便它识别我在模型构建器中的ReportAssignment上创建的复合键?

0 个答案:

没有答案