[英].Net Entity Framework Introducing FOREIGN KEY constraint exception
这是我的数据库的一部分,根据代码优先原则创建:我有一个抽象类Client(在我的数据库中创建了此类的表):
public abstract class Client
{
public int ClientId { get; set; }
[Required(ErrorMessage = "Name is required for Client")]
public string ClientName { get; set; } // name
[Required(ErrorMessage = "Phone number is required for Client")]
public string ClientPhoneNumber { get; set; } // phone number
public string Email { get; set; } // email
public string Comment { get; set; } // note
[Required(ErrorMessage = "Client should be enabled or disabled")]
public bool IsDisabled { get; set; }
}
它继承了三个类:
1)
public class PrivatePerson : Client // дядя Вася
{
public string PrivatePersonSurname { get; set; }
}
2)
public class Firm : Client
{
[Required(ErrorMessage = "Ownership is required for Firm")]
public virtual Ownership Ownership { get; set; }
[Required(ErrorMessage = "Client address is required for Firm")]
public virtual ClientAddress FirmAddress { get; set; }
}
3)
public class AdvertisingAgency : Client
{
[Required(ErrorMessage = "Ownership is required for Advertising agency")]
public virtual Ownership Ownership { get; set; }
[Required(ErrorMessage = "Client address is required for Advertising agency")]
public virtual ClientAddress AdvertisingAgencyAddress { get; set; }
}
!! 公司和AdvertisingAgency具有相似的领域
这是ClientAddress类:
public class ClientAddress
{
public int ClientAddressId { get; set; }
[Required(ErrorMessage = "Postal code is required for Client Address")]
public int PostalCode { get; set; }
[Required(ErrorMessage = "City is required for Client Address")]
public virtual City ClientCity { get; set; }
public int POBox { get; set; }
public virtual Street ClientStreet { get; set; }
public string StreetNumber { get; set; }
public int Appartment { get; set; }
public string ClientAddressComment { get; set; }
}
内容:
public virtual DbSet<Client> Clients { get; set; }
public virtual DbSet<ClientAddress> ClientAddresses { get; set; }
好吧,当我尝试创建数据库时,出现以下异常:
System.Data.SqlClient.SqlException HResult = 0x80131904消息=在表“客户端”上引入FOREIGN KEY约束'FK_dbo.Clients_dbo.ClientAddresses_FirmAddress_ClientAddressId'可能会导致循环或多个级联路径。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。 无法创建约束或索引。 请参阅先前的错误。
任何人都可以指出我的错误吗? 谢谢
这是我的背景(部分):
public class FivePlusDBContext : DbContext
{
public FivePlusDBContext() : base("name = FivePlus")
{
}
public virtual DbSet<City> Cities { get; set; }
public virtual DbSet<Street> Streets { get; set; }
public virtual DbSet<Client> Clients { get; set; }
public virtual DbSet<ClientAddress> ClientAddresses { get; set; }
public virtual DbSet<Ownership> Ownerships { get; set; }
}
要创建记录,我执行以下操作:
using (var ctx = new FivePlusDBContext())
{
City C_1 = new City() { CityName = "Name" };
ctx.Cities.Add(C_1);
ctx.SaveChanges();
}
首先,请注意,默认情况下,EntityFramework在每个层次结构中仅创建一个表(有关详细信息,请参见此处 )。 在这种情况下,会在Clients
表中添加一个特殊列(Discriminator)以区分持久类。
现在到您的问题。
根据您的模型,我假设您要对类型Firm
和AdvertisingAgency
多个客户端使用相同的ClientAddress
。 由于两个类Firm
和AdvertisingAgency
都具有类型为ClientAddress
的属性, ClientAddress
EntityFramework将在Clients表上生成两个指向ClientAddress
外键( FK_dbo.Clients_dbo.ClientAddresses_AdvertisingAgencyAddress_ClientAddressId
和FK_dbo.Clients_dbo.ClientAddresses_FirmAddress_ClientAddressId
)。 对于这两个外键,EntityFramework默认都启用级联删除。 这导致可能导致多个级联路径的例外。
有多种可能性可以解决问题。
Firm
引用其中一种,并在AdvertisingAgency
类中引用另一种(不再可以重复使用地址) Table per Concrete class (TPC)
(请参见此处也可以解决问题(未测试) 要禁用级联删除,请在您的Context类中添加以下代码。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Firm>()
.HasRequired(c => c.FirmAddress)
.WithMany()
.WillCascadeOnDelete(false);
modelBuilder.Entity<AdvertisingAgency>()
.HasRequired(c => c.AdvertisingAgencyAddress)
.WithMany()
.WillCascadeOnDelete(false);
}
提及:这可能导致孤立的地址。 删除客户端时,其地址不会被删除。 但是,该地址仍然可以与另一个客户端相关。 此外,只要该地址与至少一个客户端有关,就不可能删除该地址。 如果尝试删除仍与多个客户端相关的地址,则会引发以下异常。
保存不公开外键属性为其关系的实体时发生错误。 EntityEntries属性将返回null,因为无法将单个实体标识为异常的来源。 通过在实体类型中公开外键属性,可以简化保存时的异常处理。 有关详细信息,请参见InnerException。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.