C# WebAPI 交叉更新多个表的内连接数据

标签 c# entity-framework linq stored-procedures inner-join

here 的上一个问题来看

我愿意将这些数据更新为:

员工表:名字、姓氏 部门表:部门名称 轮类:持续时间

但是,现在我尝试修改我的 department_id 它出现错误:

属性“department_id”是对象关键信息的一部分,无法修改。

这是我对连接数据的查询:

var result = (from e in DSE.employees
             join d in DSE.departments on e.department_id equals d.department_id
             join ws in DSE.workingshifts on e.shift_id equals ws.shift_id

其次,这是我尝试修改department_id

的编码
        var result = (from e in DSE.employees
                      join d in DSE.departments on e.department_id equals d.department_id
                      join ws in DSE.workingshifts on e.shift_id equals ws.shift_id
                      where d.department_id == 1
                      select d).FirstOrDefault();

        if (result != null)
        {
            result.department_id = 2;
            DSE.SaveChanges();
        }

要求:

  • 我的ServicesEntitiesDSE
  • 我正在使用 Entity Framework
  • 我的 department_id 是连接的对象,我的 shift_id 也是如此
  • 我的“department_id”不是自动递增 ID

数据库属性:

员工表包含员工 ID、名字、姓氏、性别、薪水

部门表有department_id、department_name

WorkingShift 表具有 shift_id、持续时间

问题:

假设我想按如下方式更新数据:

员工 名字 = 堆栈, 姓氏 = 溢出,

部门 部门 ID = 4, 部门名称=网络,

转变 Shift_id = 2,

我应该按照上面的 session 执行什么编码?

最佳答案

要解决更改员工部门的问题:select d 应为 select e 以获取员工并更新员工的部门 ID,而不是部门记录的 ID。

my department table contains department_name so if I want to update my department_name then I will be using select d am I correct?

如果您想实际更改该部门的名称,则可以选择该部门实体并更改其名称。然而,这取决于这是否是您真正想要做的。如果员工指向部门 ID = 1、名称 =“部门 A”,您是否希望将该部门的名称更改为“部门 B”,还是部门 B 已存在且具有不同的 ID? (即 2)如果您将员工的 DepartmentID 指向“2”,则关联的部门详细信息将来自部门 B,这通常是您希望发生的情况。如果您想要更改部门的名称(以及与部门 ID 1 关联的所有员工显示的名称),那么您可以选择该部门并更新其名称。

查看您的原始代码:

var result = (from e in DSE.employees
              join d in DSE.departments on e.department_id equals d.department_id
              join ws in DSE.workingshifts on e.shift_id equals ws.shift_id
              where d.department_id == 1
              select d).FirstOrDefault();

if (result != null)
{
    result.department_id = 2;
    DSE.SaveChanges();
}

联接本质上是不必要的,因为您没有对部门或轮类做任何事情。这可以简化为:

var employee = DSE.employees.Where(e => e.department_id == 1)
                 .FirstOrDefault();

if (employee != null)
{
    employee.department_id = 2;
    DSE.SaveChanges();
}

当使用像 FirstOrDefault 这样的方法时,您应该始终包含 Order By 类型子句,以确保获得可预测的顺序,从而获得可重复的结果。

如果您确实想要更新相关数据,例如部门名称:

var department = DSE.departments.Single(d => d.department_id == 1);
department.name = "New Name";
DSE.SaveChanges();

这里因为我们只期望一个,并且只有 1 个部门的 ID 为 1,所以我们应该使用 Single 而不是 FirstOrDefault。如果没有找到部门,或者找到超过 1 个部门,则会抛出异常。这个异常告诉我们找到了零行或多行,这比返回“OrDefault”方法并在路上遇到 NullReferenceException 更好。

我的示例使用 EF 提供的 Fluent 方法而不是 linq QL 语法,但可以通过这种方式实现相同的行为。我只是发现流畅的方法更容易构建和链接在一起。

使用 EF,真正的威力来自于通过导航属性映射关系,因此您无需像在 SQL 中那样公开 FK 属性或手动映射 Join 表达式。 EF 可以在幕后管理所有这些。您可以加载实体并急切或延迟加载其相关实体,例如查找更新数据,或者只是从实体及其相关详细信息中选择字段,然后让 EF 构建合适的 SQL。

关于C# WebAPI 交叉更新多个表的内连接数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60518183/

相关文章:

asp.net - 使用 EntityDataSource 进行联接

c# - 读取xml属性

c# - 如何使用 LINQ 根据需要拆分的字符串列表筛选数据表?

xml - 是否有更快的方法来检查 LINQ to XML 中的 XML 元素并解析 bool?

c# - 如何使用 GC.KeepAlive() 以及用于什么目的?

C# 指针上的指针

c# - 从 SQL Server 数据库中删除

entity-framework - Entity Framework -外键-数据标注

entity-framework - Entity Framework EntityType 'UserAccount' 没有定义键

c# - 使用 System.Data.SQLite 在 C# 应用程序中缓慢打开 SQLite 连接