2012-10-12 28 views
0

我有两个实体;我们称他们为人员和地址。一个人只有一个当前地址[插入笑话关于这里的政治候选人],但也有以前的地址,这些地址也存储在地址表中。因此,我希望我的数据库表具有1:多关系。我怎样才能有1:多表,但是1:1导航属性?

然而,在我的实体类,我不希望有一个1:Person和Address之间一对多的关系,因为我在他们的当前地址只有真正感兴趣。 (如果我想知道他们以前的地址,那么我可以直接看地址表)。所以,我做而不是想在Person对象上1:many“Addresses”属性。相反,我想要1:1地址属性,我将设置为当前地址。

可以这样做吗?

+0

岂不是最自然不过的事情是以前的地址存储在一个单独的表,例如AddressHistory?他们在同一张桌子上真的很重要吗? –

+0

这是一个复杂的表格,我不希望重复结构(和伴随逻辑)。我不相信我的桌子设计应该由工具来驱动,所以我宁愿像我直接创建桌子一样构造桌子。 (我希望我先用DB)。 –

回答

0

不,不能完成。导航属性表示外键关系,并且数据库中的FK关系代表许多地址为一个人。例如,当前地址是数据库中特定查询的结果,具体取决于“当前”定义的方式 - 对给定人员的所有地址的“select top(1)... order by addresscreationdate descending”查询。在我看来

可能的解决方案是:

  • 无论是创建一个外键CurrentAddressId的人表指的当前地址的第二关系。然后,您可以在您的Person课程中获得导航参考CurrentAddress
  • 或者执行查询以使用GetCurrentAddress(Person person)方法或类似方法在存储库或服务类中加载当前地址。但是,您现在无法获得Person课程当前地址的导航属性。
+0

谢谢。我已经走了你的第一个解决方案。所以我有地址和CurrentAddress关系。 –

2

由于EF关系严格遵循DB关系,因此无法通过映射来完成此操作。此外,EF中的一对一关系基于将外键放在依赖表中的主键上(地址和人员需要具有完全相同的主键值),并且此要求不会与期望中的旧地址一起工作表格也是如此。

我想尝试这种方法(未测试):

public class MyContext : DbContext { 

    public MyContext() { 
     ((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized += 
      (sender, e) => { 
       var person = e.Person as Person; 
       if (person != null) { 
        // Fill the property manually 
        person.Address = this.Addresses.FirstOrDefault(/* some condition */); 
       } 
    } 

    protected override void OnModelCreating(DbModelBuilder builder) { 
     // Do not map the propery 
     builder.Entity<Person>().Ignore(p => p.Address); 

     // other mapping 
    } 

    public override int SaveChanges() { 

     // TODO: here you must have your own change tracking logic 
     // for address to know when the address has changed and 
     // new record must be created in the database for old address 

     return base.SaveChanges(); 
    } 

    // rest of context class 
} 
+0

谢谢+1。您的解决方案非常令人印象深刻,但对我来说太“可怕”了。我必须承认,我有一个1:多的财产*和*一个1:1的财产,正如Slauma所建议的。 –

+0

@GaryMcGill:即使你不使用它,它“太可怕”,这是你的问题的正确答案“可以做到,怎么做?”你应该接受拉迪斯拉夫的答案,而不是我的答案。 – Slauma

+0

@Slauma:OP的正确答案并不一定是解决问题的答案。我的答案主要是解决缺少功能的问题,它带来了一些缺点,如手动更改地址跟踪以及N + 1查询问题,如果您尝试加载N个人。 –

相关问题