根据上一个问题here
我能够将我的员工数据更新为他们的名字,姓氏,部门名称departmentName和工作班次作为持续时间。但是,现在我尝试修改我的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();
}
department_id
是已连接的对象,同样对我的shift_id
Employee Table has employee_id, FirstName, LastName, Gender, Salary
Department Table has department_id, department_name
WorkingShift Table has shift_id, duration
问题:1.是否有可能通过更新三个表中的三个数据在EF中解决此问题,还是我必须在存储过程中应用解决方案?2.我需要对交叉更新表数据执行什么操作?
解决更改员工部门的问题:select d
应该为select e
以获取员工并更新员工的部门ID,而不是部门记录的ID。
我的部门表包含部门名称,因此,如果我要更新部门名称,那么我将使用select d,对吗?
如果要实际更改该部门的名称,则可以选择部门实体并更改其名称。但是,这取决于您是否真的要这样做。如果某个员工指向一个部门ID = 1,名称=“部门A”,您是否要将该部门的名称更改为“部门B”?或者部门B是否已经存在具有不同ID的信息? (即2)如果将Employee的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 type子句,以确保获得可预测的订单以得到可重复的结果。
如果您确实要更新相关数据,例如部门名称:
var department = DSE.departments.Single(d => d.department_id == 1);
department.name = "New Name";
DSE.SaveChanges();
在这里,因为我们只期望一个部门,并且只有1个部门的ID为1,所以我们应该使用Single
而不是FirstOrDefault
。如果未找到任何部门,或者发现了多个部门,则将引发异常。更好的是,此异常告诉我们发现零或更多行,而不是返回“ OrDefault”方法并在随后的NullReferenceException
上触发。
我的示例使用的是EF提供的Fluent方法,而不是linq QL语法,但是可以以这种方式实现相同的行为。我只是发现流利的方法更易于构建和链接在一起。
使用EF,真正的强大之处在于通过导航属性映射关系,因此您无需像在SQL中那样公开FK属性或手动映射出Join表达式。 EF可以在后台管理所有这一切。您可以加载实体,或者渴望或延迟加载它们的相关实体,例如寻找更新数据,或者简单地从实体及其相关详细信息中选择字段,然后让EF构建合适的SQL。