外键绑定问题

Foreign Key Binding issue

你好,我有一个联系人列表。

我正在尝试 link 我的联系方式,以便使用正确的 Person_Id

填充它

示例

Id    Name    Method    Value      Person_Id  
1     John    Phone    7777777777    2
2     Joan    Phone    8888888888    8
3     Jack    Phone    9999999999    9

目前它显示 Person_Id 为所有空值,我相信我没有正确创建 ContactMethod Class。如果我能得到帮助建立一个合适的外键。我想那是我的问题。

// Primary Keys -------------------------------------------------------
public int Id { get; set; }

// Associations -------------------------------------------------------    
public virtual Person Person { get; set; }        

// Fields -------------------------------------------------------------
public string Name {get; set;
public string Value { get; set; }

我通过迁移脚本填充信息,这是一个片段

var person = people.Find(x => x.ContactBase_GUID == contactBaseGuid);

contactMethods.AddRange(channels.Select(pair => new { pair, method = reader.Get<string>(pair.Key) })
                        .Where(x => x.method != null)
                        .Select(x => new ContactMethod { Value = x.method, Person = person }));

不使用外键的工作方法。

联系方式Class

// Associations -------------------------------------------------------
public int? Person_Id { get; set; }

MigrationScript

 var person = people.Find(x => x.ContactBase_GUID == contactBaseGuid);
 contactMethods.AddRange(channels.Select(pair => new { pair, method = reader.Get<string>(pair.Key) })
                        .Where(x => x.method != null)
                        .Select(x => new ContactMethod { Value = x.method, Person = person.Id }));

我假设您有这样的模型:

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

    public virtual Person Person { get; set; }

    public string Name { get; set; }
    public string Value { get; set; }
}

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

    public string Name { get; set; }

    public virtual ICollection<Contact> Contacts { get; set; }
}

现在,要实现你想要的场景,你需要在ContactPerson之间配置一个一对多的关系。有两种方法可以做到这一点,使用 Data Annotations or using Fluent Api。在这种情况下,我将使用 Fluent Api。简单的方法是重写你的 Context 的 OnModelCreating 方法来配置关系,例如,这样:

public class YourContext : DbContext
{
    //...
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>()
            .HasMany(p => p.Contacts)
            .WithRequired(c => c.Person)
            .Map(f => f.MapKey("Person_Id"));
    }
}

如您所见,我正在指定一个未在您的联系人 class 中声明的 PK,这就是您想要的场景。现在有了这个配置,你可以这样做,例如:

Person john=new Person(){Name = "John"};

var contactList = new List<Contact>() {new Contact(){Name = "Phone",Value = "555-444-333",Person = john},
                                       new Contact() { Name = "email", Value = "john@gmail.com",Person = john}};

using (YourContext db = new YourContext())
{
   db.Contacts.AddRange(contactList);
   db.SaveChanges();
}

更新

如果您想使用数据注释进行相同的配置,您的模型将如下所示:

public class Contact
{
    [Key]
    public int Id { get; set; }

    [InverseProperty("Contacts")]
    public virtual Person Person { get; set; }

    public string Name { get; set; }
    public string Value { get; set; }
}

public class Person
{
    [Key]
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual ICollection<Contact> Contacts { get; set; }
}

如果您想使用与联系人中的人相关的 FK class,您可以这样做:

public class Contact
{
    [Key]
    public int Id { get; set; }

    public int? Person_Id { get; set; }

    [ForeignKey("Person_Id"), InverseProperty("Contacts")]
    public virtual Person Person { get; set; }

    public string Name { get; set; }
    public string Value { get; set; }
}

这样您就可以在第二个迁移脚本中直接使用 Person_Id FK:

  var person = people.Find(x => x.ContactBase_GUID == contactBaseGuid);
 contactMethods.AddRange(channels.Select(pair => new { pair, method = reader.Get<string>(pair.Key) })
                        .Where(x => x.method != null)
                        .Select(x => new ContactMethod { Value = x.method, Person_Id = person.Id }));