这是我的数据库,根据代码第一原则创建: 我有一个抽象类Client(在我的数据库中创建了这个类的表):
public class PrivatePerson : Client // дядя Вася
{
public string PrivatePersonSurname { get; set; }
}
从中继承了三个类:
1)
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; }
}
2)
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; }
}
3)
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; }
}
!!公司和AdvertisingAgency有类似的领域
这是ClientAddress类:
public virtual DbSet<Client> Clients { get; set; }
public virtual DbSet<ClientAddress> ClientAddresses { get; set; }
上下文:
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; }
}
好吧,当我试图创建一个数据库时,我得到了这个例外:
System.Data.SqlClient.SqlException 的HResult = 0x80131904 消息=引入FOREIGN KEY约束&#39; FK_dbo.Clients_dbo.ClientAddresses_FirmAddress_ClientAddressId&#39;在桌子上&#39;客户&#39;可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。 无法创建约束或索引。查看以前的错误。
请有人指出我的错误吗? 感谢
这是我的背景(部分):
using (var ctx = new FivePlusDBContext())
{
City C_1 = new City() { CityName = "Name" };
ctx.Cities.Add(C_1);
ctx.SaveChanges();
}
要创建记录,请执行以下操作:
{{1}}
答案 0 :(得分:0)
首先要注意,EntityFramework默认情况下每个层次结构只创建一个表(有关详细信息,请参阅here)。在这种情况下,将一个特殊列(Discriminator)添加到Clients
表中以区分持久类。
现在回答你的问题。
根据您的模型,我假设您希望对ClientAddress
和Firm
类型的多个客户使用相同的AdvertisingAgency
。由于类Firm
和AdvertisingAgency
都具有ClientAddress
类型的属性,因此EntityFramework将在Clients表上生成两个外键,指向ClientAddress
(FK_dbo.Clients_dbo.ClientAddresses_AdvertisingAgencyAddress_ClientAddressId
和{{ 1}})。对于这两个外键,EntityFramework默认启用级联删除。这导致例外,这可能导致多个级联路径。
有多种可能性可以解决问题。
FK_dbo.Clients_dbo.ClientAddresses_FirmAddress_ClientAddressId
中引用其中一种,并在Firm
类中引用另一种地址类型(将不再重复使用地址)AdvertisingAgency
(请参阅here也可能解决问题(未经测试)要禁用级联删除,请将以下代码添加到Context类中。
Table per Concrete class (TPC)
提及:这可能会导致孤立的地址。删除客户端时,其地址不会被删除。但是,该地址仍可能与另一个客户有关。此外,只要地址与至少一个客户端相关,就不可能删除地址。如果尝试删除仍与多个客户端相关的地址,则会抛出以下异常。
保存不公开其关系的外键属性的实体时发生错误。 EntityEntries属性将返回null,因为无法将单个实体标识为异常源。通过在实体类型中公开外键属性,可以更轻松地在保存时处理异常。有关详细信息,请参阅InnerException。