实体框架 - 代码优先 - TPH和WillCascadeOnDelete(true)

时间:2013-02-13 21:52:31

标签: ef-code-first entity-framework-5 code-first entity-relationship

使用TPH和WillCascadeOnDelete(true)时遇到问题。当我为删除级联设置值为true时,我的数据库不会被创建。异常消息如下:

  

在表'MembersProfiles'上引入FOREIGN KEY约束'FK_dbo.MembersProfiles_dbo.Contacts_ContactId'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。

为了清除这里的内容,我的模型和用于它的映射。

public class MemberProfile
{
   public Guid MemberProfileId { get; set; }
   public ICollection<Contact> Contacts { get; set; }
}

public abstract class Contact
{
   public Guid ContactId { get; set; }
   public Guid AddressId { get; set; }
   public Address Address { get; set; }
}

public class PersonContact : Contact
{
     public string Profession { get; set; }
     public string OrganizationName { get; set; }
}

public class OrganizationContact : Contact
{
     public string SalesPhone { get; set; }
     public string ServicePhone { get; set; }
}

public class ContactMap : EntityTypeConfiguration<Contact>
    {
        public ContactMap()
        {
            ToTable("Contacts");
            HasKey(c => c.ContactId);

            Property(c => c.ContactId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            Property(c => c.Name).IsRequired().HasMaxLength(50);
            Property(c => c.Email).IsRequired().HasMaxLength(150);
            Property(c => c.MobilePhone).IsRequired().HasMaxLength(15);
            Property(c => c.Description).IsOptional().HasMaxLength(500);
            Property(c => c.FixPhone).IsOptional().HasMaxLength(15);
            Property(c => c.FaxNumber).IsOptional().HasMaxLength(15);

            HasRequired(mp => mp.Address).WithMany().HasForeignKey(mp => mp.AddressId);
            HasRequired(mp => mp.Link).WithMany().HasForeignKey(mp => mp.LinkId);
            HasRequired(mp => mp.Image).WithMany().HasForeignKey(mp => mp.MediaId);
        }
    }

 public class PersonContactMap : EntityTypeConfiguration<PersonContact>
 {
        public PersonContactMap()
        {
            Property(pc => pc.Profession).IsOptional().HasMaxLength(150);
            Property(pc => pc.OrganizationName).IsOptional().HasMaxLength(150);

            Map(pc => pc.Requires("Discriminator").HasValue("PersonContact").HasColumnType("nvarchar(max)"));                }
    }

public class OrganizationContactMap : EntityTypeConfiguration<OrganizationContact>
{
        public OrganizationContactMap()
        {
            Property(oc => oc.SalesPhone).IsOptional().HasMaxLength(15);
            Property(oc => oc.ServicePhone).IsOptional().HasMaxLength(15);

            Map(oc => oc.Requires("Discriminator").HasValue("OrganizationContact").HasColumnType("nvarchar(max)"));
        }
}

public class MemberProfileMap : EntityTypeConfiguration<MemberProfile>
{
        public MemberProfileMap()
        {
            ToTable("MembersProfiles");
            HasKey(mp => mp.MemberProfileId);

            Property(mp => mp.MemberProfileId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            Property(mp => mp.Name).IsRequired().HasMaxLength(50);
            Property(mp => mp.DateOfBirth).IsRequired();
            Property(mp => mp.Email).IsRequired().HasMaxLength(150);
            Property(mp => mp.MobilePhone).IsRequired().HasMaxLength(15);
            Property(mp => mp.Summary).IsOptional();

            HasRequired(mp => mp.Address).WithMany().HasForeignKey(mp => mp.AddressId).WillCascadeOnDelete(true);
            Property(mp => mp.AddressId).HasColumnName("AddressId");

            HasOptional(mp => mp.Media).WithMany().Map(mp => mp.MapKey(new[] { "MediaId" })).WillCascadeOnDelete(true);
            HasOptional(mp => mp.Tags).WithMany().Map(mp => mp.MapKey(new[] { "TagId" })).WillCascadeOnDelete(true);
            HasOptional(mp => mp.Contacts).WithMany().Map(mp => mp.MapKey(new[] { "ContactId" })).WillCascadeOnDelete(true);
        }
}

不幸的是,我无法意识到我做错了什么......所以任何线索都会非常感激。

P.S:我正在使用EF 5.0 Code First

2 个答案:

答案 0 :(得分:1)

看看这个BlogPost helps.,另一种选择我会尝试逐个添加关系来查看它的中断位置而不是一次堆叠所有内容。有时,只需使用individual property mappings而不是Fluent API就可以了。查看我上面提到的博客上的不同链接。

答案 1 :(得分:1)

好的,发现了这个问题。我有两个表引用地址表。在我的例子中,Contacts和MemberProfile都包含对Addresses表的引用,在这两种情况下都启用了级联删除。一旦我关闭其中一个关系的级联删除一切正常。