0

我对 EF Code First 还很陌生,这可能(希望!)是一个简单的问题。

我在人员和地址之间有一个简单的关系:

People
------
PersonID
Name

Address
-------
AddressID
Address1
PersonID

大多数时候,我的 People 表中都有 AddressID;但是这个数据库有点“倒退”,因为它引用了 PersonID。在我的代码中,我处理 Person 对象并希望获取它们的关联地址。这种关系可能是 1 个人拥有多个地址,但始终是 1:1。(这是第 3 方数据库 - 我无法控制架构。)

我将如何在 Code First 中设置关系以关联人员和地址?我正在使用流利的 API,但我看不到在两个实体中都没有密钥的情况下设置它的方法。理想情况下,我希望我的实体设置如下:

Person { 
 public int PersonID {get;set;}
 public string Name {get;set;}
 //other person properites

 //navigation property
 public Address Address {get;set;}
}

Address {
 public string Address1 {get;set;}
 //other properties for address

 //navigation property
 public Person Person {get;set;}
}

我尝试了几种配置关系的方法,但总是出错。我尝试将 Address 类定义为复杂类型,但由于它是一个单独的表,这可以工作吗?此外,我尝试使用 HasOptional 和 WithOptionalDependant,但无济于事。

因此,关于如何最好地配置我的 EF CF 逻辑以允许 Address 成为 Person 中的实体的任何想法。

非常感谢任何建议或帮助。

更新 我在下面尝试了马克的建议,但我得到了一个不同的错误。(见我的评论)

我的地址实体设置将 PersonID 设置为实体键:

modelBuilder.Entity<Address>()
 .HasKey(a => a.PersonID);

modelBuilder.Entity<Address>()
 .Property(a => a.PersonID)
 .HasColumnName(<my real column name>);

所以实体在数据库中的键是 PersonID,但它也是一个返回到 Person 的 FK。这是造成问题的原因吗?(同样,不是我的数据库——它是第 3 方。)非常感谢任何帮助。谢谢!!

4

2 回答 2

1

你确定你想要一对一的关系吗?

这种关系可能是 1 个人拥有多个地址,但始终是 1:1。(这是第 3 方数据库 - 我无法控制架构。)

这意味着您实际上想要一个 1:many 关系对吗?

话虽这么说,我认为导航集合是将 Address(es) 映射到 Person 对象的理想方式:

Person { 
 public int PersonID {get;set;}
 public string Name {get;set;}
 //other person properites

 //navigation property
 public virtual ICollection<Address> Addresses {get;set;}
}

这是相应的 Fluent(这假设您有一个 PersonID 映射到地址,您在描述数据库时会这样做,但不是在您的代码中)

modelBuilder.Entity<Person>()
            .HasMany(p => p.Addresses)
            .WithRequired(a => a.Person)
            .HasForeignKey(a => a.PersonID);
于 2012-08-03T02:03:52.160 回答
0

我想通了马克的建议。

modelBuilder.Entity<Person>()
  .HasOptional<Address>(p => p.Address)
  .WithRequired(a => a.Person);

我需要设置一个可选:必需的映射,因为一个人可能没有地址(不太可能,但我想有可能),但地址有一个人,因为地址的 PK 是 PersonID。

需要注意的关键是序列化结果时 Person 和 Address 之间的循环引用(我在将结果序列化为 JSON 时在控制器中捕获了这个)。我通过在获取人员地址信息的特定查询的上下文上禁用代理创建来解决此问题:

_context.Configuration.ProxyCreationEnabled = false;

完成此操作后,我会在需要时使用延迟加载从 Person 获取我的地址信息,并且一切正常。感谢大家的帮助!

于 2012-08-03T12:14:24.130 回答