Sim*_*nca 7 c# entity-framework entity-framework-core .net-core asp.net-core
我在使用EF Core 2.2.3更新.Net Core 2.2.0中的实体时遇到问题。
保存更改时发生错误。错误详细信息:无法跟踪实体类型'Asset'的实例,因为已经跟踪了具有相同键值的{'Id'}的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。考虑使用
这是注册数据库上下文的方式:
services.AddDbContext(options =>
options.UseSqlServer(Configuration.GetConnectionString("DbConnection")), ServiceLifetime.Scoped);
Run Code Online (Sandbox Code Playgroud)
该Scoped生命周期是默认设置,但我写的更容易理解。
该Anomaly对象是这样的:
public IQueryable<Anomaly> GetAll()
{return _context.Anomalies.Include(a => a.Asset).Include(a => a.Level)
}
public async Task<Anomaly> GetAnomaly(int anomalyId, User user)
{
var anomaly = await GetAll()
.FirstOrDefaultAsync(a => a.Id == anomalyId);
return anomaly;
}
Run Code Online (Sandbox Code Playgroud)
该Update()方法如下所示:
using (var transaction = _context.Database.BeginTransaction())
{
try
{
_context.Anomalies.Update(anomaly);
_context.SaveChanges();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
它包含此事务之前的一些检查,但在此上下文中没有足够的相关性。
这是我已经跟踪实例的错误所在。我不明白这是如何发生..如果上下文Scoped,然后
...“在每种情况下,将为每个请求创建一个新的服务实例”
如果我在PUT请求上的上下文与GET请求的上下文不同,那么如何跟踪实体?在最基本的层面上如何运作?
使它工作的唯一方法是设置下,从所有条目ChangeTracker来EntityState.Detached。然后它起作用了..但是至少从我目前的知识来看,这没有任何意义。
我发现了这个问题,但没有有效答案,只有关于EF如何进行跟踪的变通办法和假设。
更新 这里是到位桶的链接,其中包含重新创建此问题的示例:EF核心更新示例
我序列化了从上下文中检索的对象。
Joe*_*tte 15
默认情况下,当您检索实体时,它们会被跟踪,并且由于它们被跟踪,您可以只调用 SaveChanges 而不是调用 Update。您还可以使用 .AsNoTracking() 检索实体而不跟踪它们
如果尚未跟踪,则需要调用 Update,因此如果您使用 AsNoTracking,那么您确实需要在 SaveChanges 之前使用 Update
public IQueryable<Anomaly> GetAll()
{ return _context.Anomalies
.Include(a => a.Asset)
.Include(a => a.Level);
}
public async Task<Anomaly> GetAnomaly(int anomalyId, User user)
{
var anomaly = await GetAll()
.AsNoTracking()
.FirstOrDefaultAsync(a => a.Id == anomalyId);
return anomaly;
}
Run Code Online (Sandbox Code Playgroud)
您还可以检查实体是否被跟踪以了解是否调用更新:
using (var transaction = _context.Database.BeginTransaction())
{
try
{
bool tracking = _context.ChangeTracker.Entries<Anomaly>().Any(x => x.Entity.Id == anomaly.Id);
if (!tracking)
{
_context.Anomalies.Update(anomaly);
}
_context.SaveChanges();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
我知道我参加这次讨论已经非常晚了,但我遇到了同样的问题,我可以毫无问题地创建一个实体,但是当涉及到更新该实体时,它第一次会成功,但此后每次都会失败。所以我尝试了上面所有的建议,但没有成功。我在文档中做了一些挖掘,发现一旦我调用,DbContext.SaveChanges()就有另一种方法可以调用DbContext.ChangeTracker.Clear()。此方法应该清除所有跟踪实体的更改跟踪器,以便您可以继续进行未来的更新。希望这能找到那些对更新实体有同样挫败感的人。
我试图在没有注意到的情况下更新相同的数据。我花了十个小时才意识到这一点。如果您有像我一样的重复值,我建议删除该数据...阅读此答案的人可能已经像我一样尝试了互联网上的所有解决方案,破坏了项目,陷入了同样的错误,并像我一样省略了重复数据. 你并不孤单,我的朋友。
model.GroupBy(gb => gb.ID).Select(s=>s.First()).ToList();//remove duplicates!!!!!
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2227 次 |
| 最近记录: |