c# - 查询未跟踪模型中的列表导致列表中的元素被跟踪
问题描述
我收到一条错误消息
附加类型为“Application.Models.DatabaseModels.Bar”的实体失败,因为同一类型的另一个实体已经具有相同的主键值。
我以前见过这个错误并且知道它正在发生,因为我试图将实例的状态设置为Bar
已修改,而上下文已经在跟踪具有相同 ID 的实例。我感兴趣的是Bar
在我尝试设置状态之前导致被跟踪的情况。
下面是两个代码块,除了在第二个块中添加了一行之外,它们在各方面都是相同的。第一个函数将正确运行,将状态更改为foo.PrimaryBar
已修改,而第二个函数将抛出错误。
这工作正常:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(ViewModel viewModel)
{
Foo foo = await _context.Foos.AsNoTracking().FirstOrDefaultAsync(f => f.Id == viewModel.FooId);
Foo.Primary.Bar = _context.Bars.AsNoTracking().First(c => c.Id == viewModel.PrimaryBarId);
_context.SetModified(foo.Primary);
//code continues
}
这会引发错误:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(ViewModel viewModel)
{
Foo foo = await _context.Foos.AsNoTracking().FirstOrDefaultAsync(f => f.Id == viewModel.FooId);
Foo.Primary.Bar = _context.Bars.AsNoTracking().First(c => c.Id == viewModel.PrimaryBarId);
//this appears to add the Bars in Foo to the context
var test = foo.Bars.Where(c => c.Id != foo.Primary.Bar.Id);
//this is where the error occurs now
_context.SetModified(foo.Primary);
//code continues
}
为情况提供上下文:
数据库模型
public class Foo
{
public int Id { get; set; }
[ForeignKey("Primary")]
public int? PrimaryId { get; set; }
public virtual Primary Primary { get; set; }
public virtual List<Bar> Bars { get; set; }
}
public class Bar
{
public int Id { get; set; }
[ForeignKey("Foo")]
public int? FooId { get; set; }
public virtual Foo Foo { get; set; }
}
public class Primary
{
[Key, ForeignKey("Foo")]
public int FooId { get; set; }
public virtual Foo Foo { get; set; }
[ForeignKey("Bar")]
public int? BarId { get; set; }
public virtual Bar Bar { get; set; }
}
查看模型
public class ViewModel
{
public int FooId { get; set; }
public int? PrimaryBarId { get; set; }
}
语境
public class AppDbContext : DbContext
{
public virtual DbSet<Foo> Foos { get; set; }
public virtual DbSet<Bar> Bars { get; set; }
public virtual DbSet<Primary> PrimaryBars { get; set; }
public virtual void SetModified<T>(T entity) where T : class
{
Entry(entity).State = EntityState.Modified;
}
}
问题
为什么该行var test = foo.Bars.Where(c => c.Id != foo.Primary.Bar.Id);
会导致Bar
's 被上下文跟踪,即使它foo
本身设置为AsNoTracking()
?
我是否误解了这里发生的事情,是什么AsNoTracking()
,或者这是实体框架本身的错误?
解决方案
推荐阅读
- google-cloud-platform - 如何在 Google Cloud Storage 中只处理一次新上传的对象?
- java - visualvm 采样器的“CPU 样本”选项卡和“线程 CPU 时间”选项卡有什么区别?
- angular - 如果不使用 MsalGuard,则 MsalService.acquireTokenRedirect 中的 Msal 交互正在进行错误
- tensorflow - 顺序批处理与并行批处理?
- python - python将带有图像模式1的png保存为pdf
- java - 如何解决 Java Exception In Initialize 错误?
- javascript - 默认路由总是在反应路由器中执行
- amazon-web-services - 从 Amazon S3 创建表时,Athena 如何将数据与正确的字段匹配?
- python - 使用 Dockerfile 部署时为空 __init__.py
- python - Django:加入两个没有外键的模型:(我可以使用多态关系,如果是,那么如何)