代码首先映射自相关的外部参照表

时间:2013-04-08 21:34:44

标签: entity-framework code-first

我已经阅读了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);

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

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

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

3 个答案:

答案 0 :(得分: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,就像您尝试过的那样。 如果您有任何问题,请告诉我。至于你的两个实体之间的关系,这就是你需要的。

答案 1 :(得分:1)

我猜是因为您使用相同的导航属性链接到PersonContact.PersonPersonContact.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);

答案 2 :(得分: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; }

我在迁移中进行了此更改,并且必须编辑生成的create table代码进行设置 在PersonContact表中,对于person表的fwo外键,级联删除为false。

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

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