在实体框架中使用父子FK

时间:2019-06-13 22:59:23

标签: c# entity-framework entity-framework-6 foreign-keys

在某些情况下,在表中使用外键的情况是FK与另一个表具有父关系或子关系,如下所示:

工作人员:

Id   |  Name  |  CityId |
-------------------------
1001 |  John  |  1      |
1002 |  Mary  |  2      |
1003 |  Bill  |  3      |
1004 |  Jose  |  4      |
1005 |  Anna  |  5      |

城市:

Id  |  Name   |  CountryId |
----------------------------
1   |  NY     |  101       |
2   |  Paris  |  102       |
3   |  London |  103       |
4   |  Rome   |  104       |
5   |  Tokyo  |  105       |

国家/地区:

Id  |  Name   | 
---------------
101 |  USA    |
102 |  France |
103 |  UK     |
104 |  Italy  |
105 |  Japan  |

我的问题是:我们应该在Staff实体中仅使用CityId作为FK,还是最好在Staff实体中包含CityId及其父CountryId?当然,将FK及其父级作为FK似乎是多余的,但是我想澄清一下,当使用这种级联关系之王时是否存在某些情况或要求?应该使用哪一个?

1 个答案:

答案 0 :(得分:1)

我将避免破坏规范化,因为没有简单的方法可以强制要求职员的Country参考和City的Country参考保持同步。例如,某个工作人员可能将“城市”设置为“多伦多”,而“国家/地区”设置为“加拿大”,但是随后某处将城市更新为“波士顿”,但没有更新“工作人员。国家/地区”。工作人员说国家是“加拿大”,而城市则是国家“美国”。谁被信任为真理之源?

在显示有关员工的信息时,请使用“视图模型”拼合相关细节。如果要显示带有国家(地区)名称的职员详细信息,而没有关于城市的其他信息,则视图模型可以基于从实体中选择的数据来显示该细节。例如:

var staffViewModels = context.Staff
    .Select(x => new StaffViewModel
    {
        StaffId = x.Id,
        Name = x.Name,
        Country = x.City.Country.Name
    }).ToList();

即使结构引入了一个由与国家相关的城市组成的工作人员地址:

var staffViewModels = context.Staff
    .Select(x => new StaffViewModel
    {
        StaffId = x.Id,
        Name = x.Name,
        Country = x.Address.City.Country.Name
    }).ToList();

该实体可以保持规范化并生成SQL以有效访问相关数据。