c# - EFCore 通过 AddAsync() 添加临时 ID

标签 c# entity-framework-core

我正在使用 EFCore 5.0.0。

当我 AddAsync (person); 时,我应该得到一个临时的 ID,我使用这个 ID 为 PersonId 添加 School(如下代码所示)。最后,我将在 SaveChangesAsync() 中保存所有内容。但是,PersonId 设置为 0。我想改为存储临时 ID。我该怎么做。

await _dbContext.AddAsync(person);

School school = mySchool;
school.PersonId = person.Id;
await _dbContext.AddAsync(school);

await _dbContext.SaveChangesAsync();

注:有很多SO post that talks about the temporary ID ,但与这篇文章无关。

最佳答案

当前接受的答案有效,但技术上不正确。分配导航属性是有效的方法,但不是强制性的。根本没有导航属性甚至是完全有效的。以及明确的 FK 属性。但是总是至少有阴影 FK 属性可用于设置/维护关系。

所以临时键的概念从一开始就是EF Core的一部分。然而,EF Core 3.0 引入了一个重大变化 - Temporary key values are no longer set onto entity instances .该链接包含对新旧行为的解释、原因和可能的解决方案:

Applications that assign primary key values onto foreign keys to form associations between entities may depend on the old behavior if the primary keys are store-generated and belong to entities in the Added state. This can be avoided by:

  • Not using store-generated keys.
  • Setting navigation properties to form relationships instead of setting foreign key values.
  • Obtain the actual temporary key values from the entity's tracking information. For example, context.Entry(blog).Property(e => e.Id).CurrentValue will return the temporary value even though blog.Id itself hasn't been set.

项目符号 #1 没有意义,项目符号 #2 是另一个答案中的建议。项目符号 #3 是您问题的直接答案/解决方案。

将它应用到你的例子中只需要改变

school.PersonId = person.Id;

school.PersonId = _contexy.Entry(person).Property(e => e.Id).CurrentValue;

当然,当您拥有导航属性和相关实体实例时,最好使用它并让 EF Core 发挥其魔力。当您没有导航属性,或者您没有相关的实体实例并且知道 key ,但不想进行往返以从数据库加载它时,临时 key 非常有用(并且使用假 stub 实体实例可以导致意想不到的副作用/行为)。它适用于显式和阴影 FK 属性。

关于c# - EFCore 通过 AddAsync() 添加临时 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66480815/

相关文章:

c# - 在使用 block 中包装对话框是多余的吗?

c# - 用c#中的图像替换文本

c# - MonthCalendar 没有点击事件?

c# - 防止使用先前输入的值自动填充文本框

c# - LINQ 方法链和粒度错误处理

entity-framework-core - Entity Framework 核心-内存提供者中必填字段

c# - 使用 EF Core 的 Crud Web API C#

c# - EF 通用存储库多个包含

c# - 英孚。连接未关闭。连接的当前状态是 connecting

c# - 对于异步操作,我应该用什么替换 IQueryable?