EF Code First Approach:通过流畅的语法在EF外键约束中混淆

时间:2013-08-16 21:43:15

标签: entity-framework foreign-key-relationship

我正在尝试使用EF代码第一种方法创建一个具有流畅语法的外键关系。

我的实体如下,

public partial class Defect
{
    public int DefectID { get; set; }
    public decimal ReleaseNo { get; set; }
    public int BuildNo { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string StepsToReproduce { get; set; }
    public int ApplicationModuleID { get; set; }
    public int SeverityLevel { get; set; }
    public string LoggedBy { get; set; }
    public Nullable<System.DateTime> LoggedOn { get; set; }
    public string LastModifiedBy { get; set; }
    public Nullable<System.DateTime> LastModifiedOn { get; set; }
    public string AssignedTo { get; set; }
    public string Status { get; set; }
    public string ResolutionNote { get; set; }
    public Nullable<System.DateTime> ResolvedOn { get; set; }
    public int ProjectID { get; set; }

    public virtual SeverityIndex SeverityIndex { get; set; }
    public virtual User LoggedByUser { get; set; }
    public virtual User LastModifiedUser { get; set; }
    public virtual User AssignedToUser { get; set; }
    public virtual Project Project { get; set; }

}
public class DefectMap:EntityTypeConfiguration<Defect>
{
    public DefectMap()
    {
        this.HasKey(d => d.DefectID);
        this.ToTable("Defect");
        this.Property(d => d.DefectID)
            .IsRequired()
            .HasColumnName("DefectID")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        this.Property(d => d.Description)
            .IsRequired()
            .IsUnicode()
            .IsVariableLength()
            .HasMaxLength(2000)
            .HasColumnName("Description")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        this.Property(d => d.StepsToReproduce)
            .IsOptional()
            .IsUnicode()
            .IsVariableLength()
            .HasMaxLength(4000)
            .HasColumnName("StepsToReproduce")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        this.Property(d => d.LastModifiedBy)
            .IsOptional()
            .IsUnicode()
            .IsVariableLength()
            .HasMaxLength(10)
            .HasColumnName("LastModifiedBy")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        this.Property(d => d.AssignedTo)
            .IsOptional()
            .IsUnicode()
            .IsVariableLength()
            .HasMaxLength(10)
            .HasColumnName("AssignedTo")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        this.Property(d => d.Status)
            .IsOptional()
            .IsUnicode()
            .IsVariableLength()
            .HasMaxLength(50)
            .HasColumnName("Status")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        this.Property(d => d.ResolutionNote)
            .IsOptional()
            .IsUnicode()
            .IsVariableLength()
            .HasMaxLength(4000)
            .HasColumnName("ResolutionNote")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

        this.HasRequired(p => p.Project).WithMany(p => p.DefectList).HasForeignKey(p => p.ProjectID);
        this.HasRequired(s => s.SeverityIndex).WithMany(s => s.DefectList).HasForeignKey(s => s.SeverityLevel).WillCascadeOnDelete();
        this.HasOptional(u => u.AssignedToUser).WithMany(u => u.AssignedToUserList).HasForeignKey(u => u.AssignedTo).WillCascadeOnDelete();
        this.HasOptional(u => u.LastModifiedUser).WithMany(u => u.ModifiedByUserList).HasForeignKey(u => u.LastModifiedBy);
        this.HasRequired(u => u.LoggedByUser).WithMany(u => u.LoggedByUserList).HasForeignKey(u => u.LoggedBy);
    }
public partial class Project
{
    public Project()
    {
        ApplicationModuleList = new List<ApplicationModule>();
        DefectList = new List<Defect>();
        UserList = new List<User>();
    }

    public int ID { get; set; }
    public string ProjectName { get; set; }
    public string ProjectManager { get; set; }
    public Nullable<System.DateTime> ProjectStartDate { get; set; }
    public Nullable<System.DateTime> ProjectEstimatedEndDate { get; set; }
    public Nullable<System.DateTime> ProjectActualEndDate { get; set; }
    public Nullable<int> ProjectBillingModel { get; set; }
    public Nullable<decimal> ProjectEstimatedBudget { get; set; }
    public Nullable<decimal> ProjectActualBudget { get; set; }
    public Nullable<int> ProjectPortfolio { get; set; }
    public Nullable<decimal> ProjectBillingRate { get; set; }
    public Nullable<int> ProjectEstimatedManHours { get; set; }
    public Nullable<int> ProjectActualManHours { get; set; }
    public Nullable<int> ProjectIsApproved { get; set; }

    public virtual ICollection<ApplicationModule> ApplicationModuleList { get; set; }
    public virtual ICollection<Defect> DefectList { get; set; }
    public virtual ICollection<User> UserList { get; set; }
    public virtual BillingModel BillingModel { get; set; }
    public virtual Portfolio Portfolio { get; set; }
    public virtual ApprovalStatus ApprovalStatus { get; set; }
}
public class ProjectMap:EntityTypeConfiguration<Project>
{
    public ProjectMap()
    {
        this.HasKey(p => p.ID);
        this.ToTable("Projects");
        this.Property(p => p.ID)
            .HasColumnName("ID")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
            .IsRequired();
        this.Property(p => p.ProjectName)
            .HasColumnName("ProjectName")
            .HasMaxLength(200)
            .IsRequired()
            .IsVariableLength()
            .IsUnicode()
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

        this.HasOptional(p => p.BillingModel).WithMany(p=>p.Projects).HasForeignKey(p => p.ProjectBillingModel).WillCascadeOnDelete();
        this.HasOptional(p => p.Portfolio).WithMany(p=>p.Projects).HasForeignKey(p => p.ProjectPortfolio).WillCascadeOnDelete();
        this.HasOptional(p => p.ApprovalStatus).WithMany(p=>p.Projects).HasForeignKey(p => p.ProjectIsApproved).WillCascadeOnDelete();
    }
}

我正在尝试使用流畅的API创建数据库的第一种方法。

然而,当我运行代码时,我收到错误

*在表'User'上引入FOREIGN KEY约束'FK_dbo.User_dbo.Projects_ProjectID'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。无法创建约束。请参阅先前的错误*

AssignedTo列显示相同的错误。

这里我试图实现逻辑,其中,一个项目可能有很多缺陷,缺陷应该有一个相关的项目ID(即项目和缺陷之间的一对多关系)。

任何人都可以建议代码出了什么问题,我应该在哪里纠正代码才能使代码生效?

提前致谢!!!

1 个答案:

答案 0 :(得分:1)

EF默认情况下启用Cascade删除,这会导致您的设计出现问题 - 根据错误消息。

添加以下内容

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
          modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
    }

或包含

 WillCascadeOnDelete(false) 

在您的流畅API中