EF Core中如何单独为HH_BetrokkeneTypes表设置AsNoTracking
EF Core插入关联实体时静态类型表重复跟踪的解决方向
问题背景
在Blazor应用中使用EF Core时,插入HH_Betrokkenen记录时抛出System.InvalidOperationException,提示HH_BetrokkeneTypes实体实例因重复键被跟踪。该表为静态类型列表,无需修改,需禁用其跟踪。原查询通过Include和ThenInclude关联HH_Dossiers、HH_Betrokkenen及HH_BetrokkeneTypes等表,单独设置AsNoTracking无效。
原查询代码:
DossierObject = context.HH_Dossiers .Include(dossier => dossier.Adres) <other unrelated includes> .Include(dossier => dossier.HH_Betrokkenen) .ThenInclude(betrok => betrok.BetrokkeneType) .Include(dossier => dossier.HH_Betrokkenen) .ThenInclude(betrok => betrok.Adres) .First(a => a.DossierID == DossierID);
尝试的替代代码:
IQueryable<HH_Betrokkenen> betrokkenen = ctx.HH_Betrokkenen.Where(x => x.DossierID == DossierID); betrokkenen = betrokkenen.Include(x => x.BetrokkeneType).AsNoTracking(); betrokkenen = betrokkenen.Include(x => x.Adres); DossierObject.HH_Betrokkenen = betrokkenen.ToList();
解决方法
1. 全局配置静态实体为无跟踪
既然HH_BetrokkenenType是静态表,直接在DbContext的OnModelCreating中配置,让EF默认不对该实体进行跟踪,从根源避免重复跟踪问题:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<HH_BetrokkenenType>() .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); }
2. 针对查询链中的特定实体设置无跟踪
如果不想全局配置,可以在查询时,针对BetrokkeneType单独设置AsNoTracking,注意链式调用的位置:
DossierObject = context.HH_Dossiers .Include(dossier => dossier.Adres) // 其他无关Include项 .Include(dossier => dossier.HH_Betrokkenen) .ThenInclude(betrok => betrok.BetrokkeneType) .AsNoTracking() // 仅对BetrokkeneType禁用跟踪 .Include(dossier => dossier.HH_Betrokkenen) .ThenInclude(betrok => betrok.Adres) .First(a => a.DossierID == DossierID);
或者使用AsNoTrackingWithIdentityResolution,确保EF不会重复跟踪同一主键的实体,同时保留实体关系的解析:
DossierObject = context.HH_Dossiers .AsNoTrackingWithIdentityResolution() .Include(dossier => dossier.Adres) // 其他无关Include项 .Include(dossier => dossier.HH_Betrokkenen) .ThenInclude(betrok => betrok.BetrokkeneType) .Include(dossier => dossier.HH_Betrokkenen) .ThenInclude(betrok => betrok.Adres) .First(a => a.DossierID == DossierID);
3. 插入前手动分离静态实体
如果查询时仍跟踪了HH_BetrokkenenType,在插入HH_Betrokkenen前,手动将关联的BetrokkeneType从上下文跟踪中分离:
// 假设要插入的实体为newBetrokkenen context.Entry(newBetrokkenen.BetrokkeneType).State = EntityState.Detached; context.HH_Betrokkenen.Add(newBetrokkenen); await context.SaveChangesAsync();
内容的提问来源于stack exchange,提问作者Stroomtang
相关产品推荐
相关产品推荐

