C# 外键依赖于另一个外键,因为它';s父密钥
我正在创建一个库,作为其他项目的基础,可以找到项目的详细信息,也可以找到nuget包 因为这是一个基本库,我想允许用户扩展模型,所以我创建的是接口,而不是具体的库(默认实现显然存在,但这超出了当前问题的范围),但由于实体框架只能用具体的类来完成导航/外键,我正在经历通用接口的过程,它工作得很好,但是我已经达到了一个点,我想基于同一个表中的另一个外键来限制外键 在寻找答案时,这个问题最接近我的要求 这里提供的解决方案说,从技术上讲,您应该删除父表键,因为子表已经有了可以用来关联到父表的父表键,我完全同意这一点,然而,在我的例子中,这是不可能的,因为它将导致循环依赖地狱,这是应该不惜一切代价远离软件项目的东西 i组织界面C# 外键依赖于另一个外键,因为它';s父密钥,c#,sql-server,entity-framework,C#,Sql Server,Entity Framework,我正在创建一个库,作为其他项目的基础,可以找到项目的详细信息,也可以找到nuget包 因为这是一个基本库,我想允许用户扩展模型,所以我创建的是接口,而不是具体的库(默认实现显然存在,但这超出了当前问题的范围),但由于实体框架只能用具体的类来完成导航/外键,我正在经历通用接口的过程,它工作得很好,但是我已经达到了一个点,我想基于同一个表中的另一个外键来限制外键 在寻找答案时,这个问题最接近我的要求 这里提供的解决方案说,从技术上讲,您应该删除父表键,因为子表已经有了可以用来关联到父表的父表键,我
public interface IOrganization<TLinkedAddress> where TLinkedAddress : ILinkedAddress
{
long ID { get; set; }
string Name { get; set; }
string Brand { get; set; }
string Genre { get; set; }
string Industry { get; set; }
string Master_Security_Stamp { get; set; }
long? Control_Branch_ID { get; set; }
[ForeignKey("Control_Branch_ID")]
TLinkedAddress Control_Branch { get; set; }
IList<TLinkedAddress> Branches { get; set; }
}
public interface ILinkedAddress
{
long ID { get; set; }
string Address { get; set; }
long LocationID { get; set; }
string AddressType { get; set; }
string Contact_Person_Name { get; set; }
string Contact_Person_Number { get; set; }
string Contact_Person_Relation { get; set; }
[ForeignKey("OrganizationID")]
long? OrganizationID { get; set; }
[ForeignKey("UserID")]
long? UserID { get; set; }
}
public interface IEducation<TUser, TOrganization, TLinkedAddress>
where TUser : IUser
where TOrganization : IOrganization<TLinkedAddress>
where TLinkedAddress : ILinkedAddress
{
long ID { get; set; }
long UserID { get; set; }
long InstituteID { get; set; }
long InstituteLocationID { get; set; }
string Degree { get; set; }
string Major { get; set; }
string Grade { get; set; }
DateTime StartDate { get; set; }
DateTime? EndDate { get; set; }
string Socities { get; set; }
string Description { get; set; }
[ForeignKey(name: "UserID")]
TUser User { get; set; }
[ForeignKey(name: "InstituteID")]
TOrganization Institute { get; set; }
[ForeignKey(name: "InstituteLocationID")]
TLinkedAddress InstituteLocation { get; set; }
}
i教育界面
public interface IOrganization<TLinkedAddress> where TLinkedAddress : ILinkedAddress
{
long ID { get; set; }
string Name { get; set; }
string Brand { get; set; }
string Genre { get; set; }
string Industry { get; set; }
string Master_Security_Stamp { get; set; }
long? Control_Branch_ID { get; set; }
[ForeignKey("Control_Branch_ID")]
TLinkedAddress Control_Branch { get; set; }
IList<TLinkedAddress> Branches { get; set; }
}
public interface ILinkedAddress
{
long ID { get; set; }
string Address { get; set; }
long LocationID { get; set; }
string AddressType { get; set; }
string Contact_Person_Name { get; set; }
string Contact_Person_Number { get; set; }
string Contact_Person_Relation { get; set; }
[ForeignKey("OrganizationID")]
long? OrganizationID { get; set; }
[ForeignKey("UserID")]
long? UserID { get; set; }
}
public interface IEducation<TUser, TOrganization, TLinkedAddress>
where TUser : IUser
where TOrganization : IOrganization<TLinkedAddress>
where TLinkedAddress : ILinkedAddress
{
long ID { get; set; }
long UserID { get; set; }
long InstituteID { get; set; }
long InstituteLocationID { get; set; }
string Degree { get; set; }
string Major { get; set; }
string Grade { get; set; }
DateTime StartDate { get; set; }
DateTime? EndDate { get; set; }
string Socities { get; set; }
string Description { get; set; }
[ForeignKey(name: "UserID")]
TUser User { get; set; }
[ForeignKey(name: "InstituteID")]
TOrganization Institute { get; set; }
[ForeignKey(name: "InstituteLocationID")]
TLinkedAddress InstituteLocation { get; set; }
}
公共接口教育
图瑟:尤瑟
组织所在地:I组织
地址:ILinkedAddress:ILinkedAddress
{
长ID{get;set;}
长用户标识{get;set;}
长机构ID{get;set;}
long InstituteLocationID{get;set;}
字符串度{get;set;}
字符串主键{get;set;}
字符串级别{get;set;}
DateTime开始日期{get;set;}
DateTime?EndDate{get;set;}
字符串社团{get;set;}
字符串说明{get;set;}
[外键(名称:“UserID”)]
TUser用户{get;set;}
[ForeignKey(名称:“InstituteID”)]
组织研究所{get;set;}
[ForeignKey(名称:“InstituteLocationID”)]
TLinkedAddress机构位置{get;set;}
}
默认实现
[Table(name: "LinkedAddress", Schema = "Arinsys_CRM")]
public class LinkedAddress : DBEntity<LinkedAddress>, ILinkedAddress
{
public long ID { get; set; }
public string Address { get; set; }
public long LocationID { get; set; }
public string AddressType { get; set; }
public string Contact_Person_Name { get; set; }
public string Contact_Person_Number { get; set; }
public string Contact_Person_Relation { get; set; }
[ForeignKey("OrganizationID")]
public long? OrganizationID { get; set; }
[ForeignKey("UserID")]
public long? UserID { get; set; }
}
[Table(name: "Organization", Schema = "Arinsys_CRM")]
public partial class Organization : DataContext.DBEntity<Organization>,
IOrganization<LinkedAddress>
{
public long ID { get; set; }
public string Name { get; set; }
public string Brand { get; set; }
public string Genre { get; set; }
public string Industry { get; set; }
public string Master_Security_Stamp { get; set; }
public long? Control_Branch_ID { get; set; }
[ForeignKey("Control_Branch_ID")]
public virtual LinkedAddress Control_Branch { get; set; }
public virtual IList<LinkedAddress> Branches { get; set; }
}
[Table(name: "Education", Schema = "Arinsys_CRM")]
public class Education : IEducation<User, Organization, LinkedAddress>
{
public long ID { get; set; }
public long UserID { get; set; }
public long InstituteID { get; set; }
public long InstituteLocationID { get; set; }
public string Degree { get; set; }
public string Major { get; set; }
public string Grade { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public string Socities { get; set; }
public string Description { get; set; }
[ForeignKey(name: "UserID")]
public virtual User User { get; set; }
[ForeignKey(name: "InstituteID")]
public virtual Organization Institute { get; set; }
[ForeignKey(name: "InstituteLocationID")]
public virtual LinkedAddress InstituteLocation { get; set; }
}
LinkedAddress.cs
[Table(name: "LinkedAddress", Schema = "Arinsys_CRM")]
public class LinkedAddress : DBEntity<LinkedAddress>, ILinkedAddress
{
public long ID { get; set; }
public string Address { get; set; }
public long LocationID { get; set; }
public string AddressType { get; set; }
public string Contact_Person_Name { get; set; }
public string Contact_Person_Number { get; set; }
public string Contact_Person_Relation { get; set; }
[ForeignKey("OrganizationID")]
public long? OrganizationID { get; set; }
[ForeignKey("UserID")]
public long? UserID { get; set; }
}
[Table(name: "Organization", Schema = "Arinsys_CRM")]
public partial class Organization : DataContext.DBEntity<Organization>,
IOrganization<LinkedAddress>
{
public long ID { get; set; }
public string Name { get; set; }
public string Brand { get; set; }
public string Genre { get; set; }
public string Industry { get; set; }
public string Master_Security_Stamp { get; set; }
public long? Control_Branch_ID { get; set; }
[ForeignKey("Control_Branch_ID")]
public virtual LinkedAddress Control_Branch { get; set; }
public virtual IList<LinkedAddress> Branches { get; set; }
}
[Table(name: "Education", Schema = "Arinsys_CRM")]
public class Education : IEducation<User, Organization, LinkedAddress>
{
public long ID { get; set; }
public long UserID { get; set; }
public long InstituteID { get; set; }
public long InstituteLocationID { get; set; }
public string Degree { get; set; }
public string Major { get; set; }
public string Grade { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public string Socities { get; set; }
public string Description { get; set; }
[ForeignKey(name: "UserID")]
public virtual User User { get; set; }
[ForeignKey(name: "InstituteID")]
public virtual Organization Institute { get; set; }
[ForeignKey(name: "InstituteLocationID")]
public virtual LinkedAddress InstituteLocation { get; set; }
}
[表(名称:“LinkedAddress”,Schema=“Arinsys\u CRM”)]
公共类LinkedAddress:DBEntity,ILinkedAddress
{
公共长ID{get;set;}
公共字符串地址{get;set;}
公共长位置ID{get;set;}
公共字符串地址类型{get;set;}
公共字符串Contact_Person_Name{get;set;}
公共字符串Contact_Person_Number{get;set;}
公共字符串联系人\个人\关系{get;set;}
[外键(“组织ID”)]
公共长?组织ID{get;set;}
[外键(“用户ID”)]
public long?UserID{get;set;}
}
Organization.cs
[Table(name: "LinkedAddress", Schema = "Arinsys_CRM")]
public class LinkedAddress : DBEntity<LinkedAddress>, ILinkedAddress
{
public long ID { get; set; }
public string Address { get; set; }
public long LocationID { get; set; }
public string AddressType { get; set; }
public string Contact_Person_Name { get; set; }
public string Contact_Person_Number { get; set; }
public string Contact_Person_Relation { get; set; }
[ForeignKey("OrganizationID")]
public long? OrganizationID { get; set; }
[ForeignKey("UserID")]
public long? UserID { get; set; }
}
[Table(name: "Organization", Schema = "Arinsys_CRM")]
public partial class Organization : DataContext.DBEntity<Organization>,
IOrganization<LinkedAddress>
{
public long ID { get; set; }
public string Name { get; set; }
public string Brand { get; set; }
public string Genre { get; set; }
public string Industry { get; set; }
public string Master_Security_Stamp { get; set; }
public long? Control_Branch_ID { get; set; }
[ForeignKey("Control_Branch_ID")]
public virtual LinkedAddress Control_Branch { get; set; }
public virtual IList<LinkedAddress> Branches { get; set; }
}
[Table(name: "Education", Schema = "Arinsys_CRM")]
public class Education : IEducation<User, Organization, LinkedAddress>
{
public long ID { get; set; }
public long UserID { get; set; }
public long InstituteID { get; set; }
public long InstituteLocationID { get; set; }
public string Degree { get; set; }
public string Major { get; set; }
public string Grade { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public string Socities { get; set; }
public string Description { get; set; }
[ForeignKey(name: "UserID")]
public virtual User User { get; set; }
[ForeignKey(name: "InstituteID")]
public virtual Organization Institute { get; set; }
[ForeignKey(name: "InstituteLocationID")]
public virtual LinkedAddress InstituteLocation { get; set; }
}
[表(名称:“组织”,Schema=“Arinsys\u CRM”)]
公共部分类组织:DataContext.DBEntity,
组织
{
公共长ID{get;set;}
公共字符串名称{get;set;}
公共字符串品牌{get;set;}
公共字符串类型{get;set;}
公共字符串行业{get;set;}
公共字符串Master_Security_Stamp{get;set;}
公共长?控制分支ID{get;set;}
[ForeignKey(“控制分支机构ID”)]
公共虚拟链接地址控件_分支{get;set;}
公共虚拟IList分支{get;set;}
}
Education.cs
[Table(name: "LinkedAddress", Schema = "Arinsys_CRM")]
public class LinkedAddress : DBEntity<LinkedAddress>, ILinkedAddress
{
public long ID { get; set; }
public string Address { get; set; }
public long LocationID { get; set; }
public string AddressType { get; set; }
public string Contact_Person_Name { get; set; }
public string Contact_Person_Number { get; set; }
public string Contact_Person_Relation { get; set; }
[ForeignKey("OrganizationID")]
public long? OrganizationID { get; set; }
[ForeignKey("UserID")]
public long? UserID { get; set; }
}
[Table(name: "Organization", Schema = "Arinsys_CRM")]
public partial class Organization : DataContext.DBEntity<Organization>,
IOrganization<LinkedAddress>
{
public long ID { get; set; }
public string Name { get; set; }
public string Brand { get; set; }
public string Genre { get; set; }
public string Industry { get; set; }
public string Master_Security_Stamp { get; set; }
public long? Control_Branch_ID { get; set; }
[ForeignKey("Control_Branch_ID")]
public virtual LinkedAddress Control_Branch { get; set; }
public virtual IList<LinkedAddress> Branches { get; set; }
}
[Table(name: "Education", Schema = "Arinsys_CRM")]
public class Education : IEducation<User, Organization, LinkedAddress>
{
public long ID { get; set; }
public long UserID { get; set; }
public long InstituteID { get; set; }
public long InstituteLocationID { get; set; }
public string Degree { get; set; }
public string Major { get; set; }
public string Grade { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public string Socities { get; set; }
public string Description { get; set; }
[ForeignKey(name: "UserID")]
public virtual User User { get; set; }
[ForeignKey(name: "InstituteID")]
public virtual Organization Institute { get; set; }
[ForeignKey(name: "InstituteLocationID")]
public virtual LinkedAddress InstituteLocation { get; set; }
}
[表(名称:“教育”,Schema=“Arinsys\u CRM”)]
公营教育:教育
{
公共长ID{get;set;}
公共长用户标识{get;set;}
公共长机构ID{get;set;}
公共长期机构定位ID{get;set;}
公共字符串度数{get;set;}
公共字符串主键{get;set;}
公共字符串等级{get;set;}
公共日期时间起始日期{get;set;}
公共日期时间?结束日期{get;set;}
公共字符串社团{get;set;}
公共字符串说明{get;set;}
[外键(名称:“UserID”)]
公共虚拟用户用户{get;set;}
[ForeignKey(名称:“InstituteID”)]
公共虚拟组织机构{get;set;}
[ForeignKey(名称:“InstituteLocationID”)]
公共虚拟链接地址机构位置{get;set;}
}
现在的问题是,在IEducation
接口中,是否有可能对instituteLocationID
施加约束,即它必须是组织的一个分支,由InstituteID
定义,否则我将别无选择,只能让最终开发人员自己施加约束
编辑:进一步研究
我开始研究@Ivan Starostin建议的可传递依赖关系,并偶然发现@Jeff Atwood(Stack Overflow的联合创始人(荣誉退休人员)和联合创始人)关于他们在2008年面临的堆栈溢出问题的这篇很棒的博文
这篇博文的总结是,规范化并不是万能的,有时非规范化的数据实际上会带来更好的生产力和性能,尽管这篇博文没有回答确切的问题,但它帮助我获得了更深入的理解,所以在这里为未来的读者发帖。这是一个有点理论性的问题。InstituteID不是教育实体的属性,而是LinkedLocation实体的属性。所以你在教育实体中有一个传递依赖,这意味着它不是第三范式:InstituteID依赖于InstituteLocationID。因此,您必须将InstituteID视为无关系约束的非规范化数据,或者将其从教育实体中删除。此外,我认为问题来自LinkedAddress实体-它是地址实体和附加链接实体的混合体,应该存储地址和组织之间的链接。所以,如果您从LinkedAddress提取实体地址,并使LinkedAddress成为一个真正的链接实体,它存储AddressID和OrganizationID的元组,这可能会使模型更加清晰,并显示InstituteLocation