更新实体而不知道主键
给定以下代码,如何在不知道其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只是一个我们用于外部参考的guid。这不工作,因为它没有设置id,但没有击中数据库,我们不能拥有它。
如果您需要从另一个实体(entity
)引用实体(referencedEntity
),则必须使用实体框架,您必须知道referencedEntity
。
否则,您可以添加仅将实体设置referencedEntity
添加为空。
要知道referencedEntity或者您知道Id
或者您必须以某种方式(从数据库)检索它。
在SQL(DML)中,如果(且仅当)ExternalId
是候选键noy可为空,则可以插入OnBoardingProcessVisit
记录,但插入语句将包含内部查询。
OnBoardingProcessVisit.OnBoardingProcess_Id = (
SELECT
Id
FROM
OnBoardingProcess
WHERE
ExternalId = @propertyId)
编辑
没有办法生成与EF该查询。你可以看看外部组件(免费而不是免费的,例如EntityFramework Extended,但在这种情况下,我认为这没有帮助)。
在这种情况下,我可能会尝试使用标准实体框架功能(因此从ExternalId
中检索OnBoardingProcess
需要1次往返)。
然后,如果往返速度太慢,请直接在数据库上运行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);
感谢您对输入,问题是,我该如何让EF生成脚本就像在你的榜样?现在我可以在EF中说,外部ID是一个候选键。 – Marco
请参阅答案中的编辑部分 – bubi
看来我可以在最新版本的EF中使用HasAlternateKey :(感谢您的帮助。 – Marco