实体框架多对多关系到相同的实体类型,但具有不同的关系类型
本文关键字:实体 类型 关系 框架 关系到 | 更新日期: 2023-09-27 17:54:21
使用实体框架6,我有一个Person类…
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Relationship> Relationships { get; set; }
}
和关系类
public class Relationship
{
public int ID { get; set; }
public RelationshipType DependencyType { get; set; }
[ForeignKey("Person")]
public int PersonID { get; set; }
public virtual Person Person { get; set; }
public virtual ICollection<Person> RelatedPersons { get; set; }
}
我想要它表示的是,例如,我可能将sibling作为关系类型,UnclesAndAunts作为另一种关系类型,并且不需要知道这些类型的关系是谁,因为他们可能不在数据库中。
使用Code First,这将生成一个表模式…
CREATE TABLE [dbo].[Person](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](max) NULL,
[Relationship_ID] [int] NULL)
和
CREATE TABLE [dbo].[Relationship](
[ID] [int] IDENTITY(1,1) NOT NULL,
[RelationshipType] [int] NOT NULL,
[PersonID] [int] NOT NULL,
[Person_ID] [int] NULL)
PersonID is the main Person of this relationship.
Person_ID is the Person to whom the main person is related to.
I would see the Relationship table containing repeated PersonID data.
这样做的问题是,由于Person表中的Relationship_ID这意味着Person表将具有重复数据而我希望Relationship表具有重复数据,例如
Relationship...
ID RelationshipType PersonID Person_ID
---------------------------------------------
1 Sibling 1 2
2 Sibling 1 3
3 UnclesAndAunts 1 4
谁能告诉我我应该如何用模型类来表示这个,我假设有一些属性或其他我需要包括的。
谢谢
Relationship_ID
来自Relationship.RelatedPersons
集合。我认为在这里有一个集合是不正确的,相反,它应该是一个单独的参考 RelatedPerson
(单数),因为一个单独的Relationship
实体描述了两个人之间的关系,而不是一个人和一组其他人之间的关系。所以,我建议这样修改模型:
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
[InverseProperty("Person")]
public virtual ICollection<Relationship> Relationships { get; set; }
}
public class Relationship
{
public int ID { get; set; }
public RelationshipType DependencyType { get; set; }
[ForeignKey("Person")]
public int PersonID { get; set; }
public virtual Person Person { get; set; }
[ForeignKey("RelatedPerson")]
public int RelatedPersonID { get; set; }
public virtual Person RelatedPerson { get; set; }
}
[InverseProperty]
属性在这里很重要,它告诉EF Relationship.Person
是Person.Relationships
的逆导航属性。如果没有该属性,您将在引用Person
表的Relationship
表中获得三个外键。
您可能还需要禁用其中一个关系的级联删除,以避免从Person
到Relationship
的禁止多个级联删除路径的异常。这可以用Fluent API完成:
modelBuilder.Entity<Relationship>()
.HasRequired(r => r.RelatedPerson)
.WithMany()
.HasForeignKey(r => r.RelatedPersonID)
.WillCascadeOnDelete(false);
一旦你有了这个,你可以添加第二个关系与Fluent API,这将允许你从模型中删除所有的属性,因为它们是多余的,然后:
modelBuilder.Entity<Relationship>()
.HasRequired(r => r.Person)
.WithMany(p => p.Relationships)
.HasForeignKey(r => r.PersonID);