一个人可以有很多同事而一个同事就是一个人。是否可以在ColleagueId
和PersonId
上制作群集密钥?
好的,我不太确定,但是同事类只是因为数据库应该理解与Person
的连接。所以,实际上我不需要Colleague
类。我怎么能这样做,数据库知道Person
有一个Colleagues
的{{1}}列表?
在该计划中,我们可以创建Person
,然后我们就可以将其他Persons
添加到Persons
的{{1}}列表中!
我的解释感到多云,但我不知道如何用其他任何方式解释它。
同事班:
Persons
人员类:
Colleagues
答案 0 :(得分:1)
我使用OrmLite v3(不支持复杂的主键)。我在那里使用的工作是创建一个新属性,它是两个键的组合,我用作键:
public class Colleague
{
public int ColleagueId { get; set; }
public int PersonId { get; set; }
[Key]
public string CombinedId {
get { return ColleagueId.ToString() + PersonId.ToString(); }
}
}
我使用string
类型来避免得到两个int
值的总和(这可能会导致密钥冲突,尽管不完全安全,具体取决于int数字)。当然,您可以根据自己的类型进行调整。
答案 1 :(得分:0)
您基本上希望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
是-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>
。