您基本上想要Person 实体之间的多对多关系。为此,您需要一个联结表来链接成对的Person 实体。如果我们称这个实体为WorkRelationship:
class WorkRelationship
{
[Key]
[Column(Order = 1)]
[ForeignKey("Myself")]
public int MyselfId { get; set; }
public virtual Person Myself { get; set; }
[Key]
[Column(Order = 2)]
[ForeignKey("Colleague")]
public int ColleagueId { get; set; }
public virtual Person Colleague { get; set; }
}
然后我们像这样修改Person:
class Person
{
public int Id { get; set; }
public string Name { get; set; }
[InverseProperty("Myself")]
public virtual ICollection<WorkRelationship> WorkRelationships { get; set; }
public void AddWorkRelationship(Person colleague)
{
if (WorkRelationships == null)
{
WorkRelationships = new List<WorkRelationship>();
}
WorkRelationships.Add(new WorkRelationship { Myself = this, Colleague = colleague });
}
}
所以你可以看到Person 现在有一个WorkRelationships 的集合:通过向这个集合中添加一个实体,你不仅可以将此人链接到他/她的同事,还可以创建反向关系。我还添加了一个辅助方法,以便您可以轻松添加关系。
这是一个非常基本的数据库上下文类,可用于管理这些实体:
sealed class MyContext : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<WorkRelationship> WorkRelationships { get; set; }
public IEnumerable<Person> GetColleagues(int personId)
{
List<WorkRelationship> relationships =
WorkRelationships
.Include(x => x.Myself)
.Include(x => x.Colleague)
.Where(x => x.MyselfId == personId || x.ColleagueId == personId)
.ToList();
foreach (WorkRelationship relationship in relationships)
{
if (relationship.Myself.Id == personId)
{
yield return relationship.Colleague;
}
else if (relationship.Colleague.Id == personId)
{
yield return relationship.Myself;
}
}
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
}
}
我还为此添加了一个辅助方法,它将检索给定人员的同事。
我们现在可以创建一个简单的测试程序来插入和查询人员:
static void Main(string[] args)
{
var alice = new Person { Name = "Alice" };
var bob = new Person { Name = "Bob" };
var colin = new Person { Name = "Colin" };
var davina = new Person { Name = "Davina" };
alice.AddWorkRelationship(bob);
alice.AddWorkRelationship(colin);
bob.AddWorkRelationship(davina);
using (var db = new MyContext())
{
db.People.AddRange(new[] { alice, bob, colin, davina });
db.SaveChanges();
}
using (var db = new MyContext())
{
Console.WriteLine("Bob works with:");
foreach (Person colleague in db.GetColleagues(bob.Id))
{
Console.WriteLine(colleague.Name);
}
}
Console.ReadLine();
}
原始答案如下(包含在上下文中)
如果Colleague is-a Person,那么你应该这样建模:
public class Colleague : Person
{
// don't need any other properties based on what you've posted
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public byte[] Image { get; set; }
public virtual ICollection<Conversation> Conversations { get; set; }
public virtual ICollection<Colleague> Colleagues { get; set; }
}
(我已将用于保存同事集合的属性名称复数)。
然后,EF Code First 应该创建一个单独的 Person 表,其中包含一个额外的 Discriminator 列,用于区分 Person 和 Colleague 实体。
再想一想,我什至不确定您是否需要单独的 Colleague 实体。你可能会侥幸逃脱:
public class Person
{
...
public virtual ICollection<Person> Colleagues { get; set; }
}
注意ICollection<Person> 而不是ICollection<Colleague>。