如何在EF中选择特定字段进行更新

6

我想使用 @where 条件从数据库中获取所有记录,然后对它们进行更新。为此,我创建了以下查询:

public async Task MarkAllAsActive()
{
    var currentUserId = _userManager.GetCurrentUserId();
    await _workOrders.Where(row => row.Status == WorkOrderStatus.Draft).ForEachAsync(row =>
    {
        row.Status = WorkOrderStatus.Active;
        _uow.MarkAsChanged(row, currentUserId);
    });
}

但是这个查询选择了数据库中的所有字段,这并不好。为了解决这个问题,我尝试仅选择特定的字段,比如IDStatus

public async Task MarkAllAsActive()
{
    var currentUserId = _userManager.GetCurrentUserId();
    await _workOrders.Select(row=>new WorkOrder { Id=row.Id,Status=row.Status}).Where(row => row.Status == WorkOrderStatus.Draft).ForEachAsync(row =>
    {
        row.Status = WorkOrderStatus.Active;
        _uow.MarkAsChanged(row, currentUserId);
    });

}

但是它返回了这个错误:

在LINQ to Entities查询中,实体或复杂类型'DataLayer.Context.WorkOrder'无法构造。

我看到了一个类似的帖子和相同的错误,但我的问题不同,因为我想要更新。

我该怎么做?


尝试使用 .Select(row=>new {Id =row.Id,Status=row.Status}),linq to entities 允许使用匿名类型投影。在我看来,你应该先使用 Where,然后使用 Select 选择所需的项目。 - M. Wiśnicki
@M.Wiśnicki,有一个问题。状态是一个枚举类型,现在我无法将枚举类型设置为状态,它显示无法分配给 - -,因为它是一个匿名类型。 - work question
还需要添加 _uow.MarkAsChanged()。我认为你正在尝试以错误的方式进行更新。 - M. Wiśnicki
1
考虑这次使用原始 SQL,并使用常规的 UPDATE workorders SET Status = ? WHERE Status = ?; 查询。很遗憾,没有任何方法可以通过 Entity Framework 完成此操作,但如果您关心性能,则这是最佳方法。 - jorgonor
1
@workquestion 对不起,关于我的想法... 这是我更新表中字段的方式。首先将其查询到 ToList 中,然后使用 ForEach > SingleOrDefault 再次查询并保存。 - KiRa
显示剩余3条评论
2个回答

1

不幸的是,您必须获取整个实体。 要使用EF更新实体,编辑的类类型必须是DbContext映射实体。

如果您想在不将实体获取到服务器且不编写任何SQL的情况下进行更新,则可以使用Entity Framework Extended Library

请参阅网站上的更新部分。


0

在您的情况下,从同一实体中获取实体将无法工作,因为您仅获取了选定的列。例如,您正在再次获取WorkOrder实体中的WorkOrder实体。 我建议您使用DTO仅加载选定的列。它应该可以工作。但在更新时,您将不得不将其复制到数据库对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接