鉴于以下代码,如何在不知道其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,但没有点击数据库,我们无法拥有它。
答案 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);