在没有知道主键的情况下更新实体

时间:2017-08-11 08:46:55

标签: entity-framework entity-framework-6

鉴于以下代码,如何在不知道其ID并从数据库中检索它的情况下,将元素添加到实体的某个属性中?

    public async Task BookInPersonVisitAsync(Guid propertyId, DateTime dateTime, CancellationToken token)
    {
        var entity = new OnBoardingProcessEntity{ ExternalId = propertyId };

        DbContext.OnBoardingProcesses.Attach(entity);

        entity.OnBoardingProcessVisits.Add(new OnBoardingProcessVisitEntity
        {
            DateTime = dateTime,
            Occurred = false
        });

        await DbContext.SaveChangesAsync(token);
    }

ExternalId只是我们用于外部参考的指导。这不起作用,因为它没有设置id,但没有点击数据库,我们无法拥有它。

1 个答案:

答案 0 :(得分:0)

如果您必须从另一个实体(referencedEntity)引用实体(entity),则使用实体框架,您必须知道referencedEntity
否则,您只需添加实体设置referencedEntity即可 要知道referencedEntity或者您知道Id,或者您必须以某种方式(从数据库)检索它。

在SQL(DML)中,如果(且仅当)ExternalId是候选键noy nullable,您可以使用单个往返插入OnBoardingProcessVisit记录,但insert语句将包含内部查询。

  OnBoardingProcessVisit.OnBoardingProcess_Id = (
    SELECT 
      Id 
    FROM 
      OnBoardingProcess 
    WHERE 
      ExternalId = @propertyId)

修改
无法使用EF生成该查询。您可以查看外部组件(免费而非免费,例如EntityFramework Extended,但在这种情况下,我认为这没有帮助)。

在这种情况下,我可能会尝试使用标准实体框架功能(所以1往返从OnBoardingProcess检索ExternalId)。
然后,如果往返太慢,则直接在数据库上运行SQL查询 关于性能(和数据库一致性)在OnBoardingProcess.ExternalId上添加唯一索引(在每种情况下)。

如果你决定进行往返,还有另一个建议。 在您的代码中,entity将是代理。如果您不禁用延迟加载,使用您的代码,当您访问属性时,您将再进行一次往返 entity.OnBoardingProcessVisits(在entity.OnBoardingProcessVisits.Add声明中) 因此,在这种情况下,请禁用延迟加载或使用不同的方式执行相同操作 在你的情况下,不同的方式是

var onBoardingProcessVisitEntity  new OnBoardingProcessVisitEntity
{
    DateTime = dateTime,
    Occurred = false,
    OnBoardingProcess = entity
});

DbContext.OnBoardingProcessVisits.Add(onBoardingProcessVisitEntity);
await DbContext.SaveChangesAsync(token);