1

我已经阅读了 StackOverflow 上的几个线程,但无法弄清楚这一点。我希望有人可以提供一些建议。我有一些看起来像这样的 POCO 类:

Person
{
  int PersonCode {get; set;}
  ...
  virtual List<PersonContact> {get; set;}
}

PersonContact
{
  int PersonPersonCode {get; set;}
  int ContactPersonCode {get; set;}
  int PersonContactTypeCode {get; set;}

  virtual PersonContactType {get; set;}
  virtual Person Person {get; set;}    // not sure I really need this one
  virtual Person Contact {get; set;}
}

每个 Person 记录将有零到多个 PersonContact 记录。每个 PersonContact 记录将一个 Person 记录链接到另一个 Person 记录,并使用 PersonContactTypeCode 指示两个 Person 记录之间的关系类型。

我需要能够对此进行映射,以便可以将 Person 记录导航到他的相关 PersonContact 记录。像这样的东西:

var john = new Person(...);
var david = new Person(...);
john.PersonContacts.Add(new PersonContact
  {
    Contact = david,
    PersonContactType = ... // manager
  });

进而

john.PersonContacts
  .Where(c => c.PersonContactType.PersonContactTypeCode == "manager")
  .FirstOrDefault();

会回来

david

我已经尝试过很多 Data Annotations 和 Fluent API 的组合,以至于我几乎不记得我从哪里开始了。我似乎对这个组合有最好的运气:

modelBuilder.Entity<Person>()
    .HasMany(entity => entity.PersonContacts)
        .WithRequired(person => person.Person)
        .HasForeignKey(xref => xref.PersonPersonCode)
        .WillCascadeOnDelete(false);

modelBuilder.Entity<Person>()
    .HasMany(entity => entity.PersonContacts)
        .WithRequired(xref => xref.Contact)
        .HasForeignKey(entity => entity.ContactPersonCode)
        .WillCascadeOnDelete(false);

但是,当我尝试向一个人添加多个 PersonContact 时,我收到此错误:

Multiplicity constraint violated. The role 'Person_PersonContacts_Source' of the
relationship '...Entities.Person_PersonContacts' has multiplicity
1 or 0..1.

我真的很感激任何帮助,我现在完全被难住了。顺便说一句,如有必要,我愿意更改这些 POCO。

4

3 回答 3

1

试试这个:

public class Person
{
   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int PersonId {get; set;}
   ...
   public virtual ICollection<PersonContact> PersonContacts {get; set;}
}


public class PersonContact
{
   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int ContactId {get; set;}

   [ForeignKey("Person"), DatabaseGenerated(DatabaseGeneratedOption.None)]
   public int PersonId {get; set;}       

   public virtual Person Person {get; set;}         
}

我已经使用Property Mapping而不是Fluent Mapping像你在你的尝试中尝试过的那样。如果您有任何问题,请告诉我。至于你的两个实体之间的关系,这就是你所需要的。

于 2013-04-08T22:33:16.447 回答
1

我猜这是因为您使用相同的导航属性链接到PersonContact.Personand PersonContact.Contact

假设:

Person
{
  int PersonCode {get; set;}
  ...
  virtual ICollection<PersonContact> PersonContacts {get; set;}
}

尝试类似:

modelBuilder.Entity<PersonContact>()
    .HasRequired(x => x.Person)
        .WithMany(x => x.PersonContacts)
        .HasForeignKey(x => x.PersonPersonCode)
        .WillCascadeOnDelete(false);

modelBuilder.Entity<PersonContact>()
    .HasRequired(x => x.Contact)
        .WithMany()
        .HasForeignKey(x => x.ContactPersonCode)
        .WillCascadeOnDelete(false);
于 2013-04-08T23:30:42.193 回答
0

我设法使用类似这样的东西来完成类似的工作

在我的域类中

public class PersonContact
{
    public int Id { get; set; }

    [Required]
    public virtual Person ContactPerson { get; set; }

    [Required]
    public virtual Person Person { get; set; }

[Required]
public int ContactType { get; set; }

}

public class Person
{
int Id { get; set; }

    private readonly  List<PersonContact> _contacts = new  List<Contact>();

    public virtual  List<PersonContact> Contacts
    {
        get
        {
            return this._contacts;
        }
    }
}

在我的上下文中

 public DbSet<Person> People { get; set; }
 public DbSet<PersonContact> Contacts { get; set; }

我在迁移中进行了此更改,并且必须编辑生成的创建表代码以将 Cascade delete 设置为 false,以便在 PersonContact 表内将人员表的 fwo 外键设置为 false。

我在 PersonContact 表中得到一个额外的 Person_Id1 列。它似乎填充了与 Person_Id 相同的数据。当我创建绑定源时,EF 似乎需要这 - 因为没有它我会出错。

我不会将显式外键放入,让迁移创建它们。

于 2013-04-08T22:42:07.377 回答