question

senglory-6433 avatar image
0 Votes"
senglory-6433 asked ·

Ef Core - weird behavior of AddRange

Here's my code:

 [Table("prom_term", Schema = "demo")]
     public class PromTerm
     {
         [Key]
         [Column("promotion_terminal_id")]
         [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
         public int Id { get; set; }
         [Column("promotion_id")]
         public int Promotionld { get; set; }
         [ForeignKey("Promotionld")]
         public DbPromotion Promotion { get; set; }
         [Column("pos_terminal_id")]
         public string POSTerminalld { get; set; }
         [Column("retailer_name")]
         public string RetailerName { get; set; }
         [Column("promotion_report_period_id")]
         public int ReportPeriodld { get; set; }
         [ForeignKey("ReportPeriodId")]
         public PromReportPeriod RepoortPeriod { get; set; }
     }
    
     public class FamilyTeamSvcDbContext : DbContext
     {
    
         ...
         public DbSet<PromTerm> PromotionTerminals { get; set; }
     }
    
             using var ctx = new FamilyTeamSvcDbContext(options);
             var promoTerminals = new List<PromTerm>{
                     new PromTerm
                     {
                         POSTerminalId="777777", 
                         RetailerName="8888"
                     },
                     new PromTerm
                     {
                         POSTerminalId="333",
                         RetailerName="AAA"
                       },
                       new PromTerm
                     {
                         POSTerminalId="qqq",
                         RetailerName="AAA"
                     },
                     new PromTerm
                     {
                         POSTerminalId="qqq",
                         RetailerName="BBB"
                     }
                 }
                 ;
             promoTerminals.ForEach(x => {
                 x.Promotionld = 1;
                 x.ReportPeriodld = 2;
                 //ctx.PromotionTerminals.Append(x);
                 }
             );
    
             ctx.PromotionTerminals.AddRange(promoTerminals);




Right at the last line I get this exception:

System.InvalidOperationException : The instance of entity type 'PromTerm' cannot be tracked because another instance with the same key value for {'PromotionId', > 'POSTerminalId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using > 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
Stack Trace:
IdentityMap`1.ThrowIdentityConflict(InternalEntityEntry entry)
IdentityMap`1.Add(TKey key, InternalEntityEntry entry, Boolean updateDuplicate)
IdentityMap`1.Add(TKey key, InternalEntityEntry entry)
NullableKeyIdentityMap`1.Add(InternalEntityEntry entry)
StateManager.StartTracking(InternalEntityEntry entry)
InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties)
InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Boolean modifyProperties, Nullable`1 forceStateWhenUnknownKey)
EntityGraphAttacher.PaintAction(EntityEntryGraphNode`1 node)
EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1 node, Func`2 handleNode)
EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState targetState, EntityState storeGeneratedWithKeySetTargetState, Boolean > forceStateWhenUnknownKey)
InternalDbSet`1.SetEntityState(InternalEntityEntry entry, EntityState entityState)

I> nternalDbSet`1.SetEntityStates(IEnumerable`1 entities, EntityState entityState)

InternalDbSet`1.AddRange(IEnumerable`1 entities)


Why does it treat 'PromotionId' +'POSTerminalId' as a key still a bit beyond me. My schema does not have these fields as a multi-column key. But there's one more weird behavior — if I uncomment Append() and comment AddRange(), then adding starts working. What am I doing wrong?

dotnet-entity-framework-core
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

DanielZhang-MSFT avatar image
0 Votes"
DanielZhang-MSFT answered ·

Hi senglory-6433,
The error indicates that your DB Context is being shared by multiple requests, meaning that the entity you're editing has been tracked already.
This is most likely because your repository service is Singleton instead of Scoped, so when you pull the database context and put it back into the same instance of the database context, the database context will be reused.
And when you call DbContext.AddRange method, it indicates that the entity has been tracked and is in the added state.
So I suggest you can disable tracking via AsNoTracking or changing EntityState to Detached.
Best Regards,
Daniel Zhang


If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


· 3 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi DanielZhang,

Turned out that the issue was with key defined as PromotionId' +'POSTerminalId in OnModelCreating.

0 Votes 0 ·

Hi @senglory-6433,
Did you disable tracking and still get the same error?
Best Regards,
Daniel Zhang

0 Votes 0 ·

Yes, in my case tracking has no relation to fixing the issue, only OnModelCreating rewriting.

0 Votes 0 ·