实体框架中指向同一个表的多个外键是不可区分的

本文关键字:可区分 实体 同一个 框架 | 更新日期: 2023-09-27 18:00:05

当两个或多个外键通过数据库上下文指向同一个表时,我无法区分外键。

例如,如果我有一个数据库,其中有两个表,Users和Invoices。

Users has two fields: userId and userName
Invoices has three fields: invoiceNumber, cashierUserId, supervisorUserId

cashierUserId和supervisorUserId是指向Users表中userId的外键。

现在,在实体框架中,通过数据库上下文,当我试图获取出纳或主管的用户名时,我无法判断要获取哪个用户名。

dbContext.Invoices.Single(i => i.invoiceNumber == 1).Users.userName;

我得到哪个用户名?收银员的还是主管的?我该如何告诉它我想要哪一个?

实体框架中指向同一个表的多个外键是不可区分的

首先,您的代码有一个问题。"Users"集合将没有名为"userName"的属性。它可能应该是:

dbContext.Invoices.Single(i => i.invoiceNumber == 1).Users.First().userName;

显然。First()对"区分"问题没有帮助。为此,我看到了两种解决方案:

  1. 修改您的上下文,使每个导航属性都有一个特殊的名称("出纳"、"主管")。然后你只需要写:

    dbContext.Invoices.Single(i => i.invoiceNumber == 1).Cashier.userName;
    
  2. 为用户提供一个"类型"字段。这可能是存储在用户表中的字符串,也可能是"UserTypes"表(在规范化数据库中)中的外键。然后您的查询变成:

    dbContext.Invoices.Single(i => i.invoiceNumber == 1).Users.First(u => u.UserType == "Cashier").userName;
    

使用不同的表会稍微改变谓词,但你已经明白了。为了帮助指导您的设计,请记住EF与标准SQL没有太大区别。您将如何创建一个标准的SQL查询来区分这两者?您可以基于外键(第一个选项)或users表上的另一个字段(第二个选项)。