Странное поведение EF Core - часть 2
От: senglory  
Дата: 12.03.21 19:59
Оценка:
    [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);



Падает на последней строке с вот такой хренью:

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)
InternalDbSet`1.SetEntityStates(IEnumerable`1 entities, EntityState entityState)
InternalDbSet`1.AddRange(IEnumerable`1 entities)



Вчесть чего оно решило что 'PromotionId' +'POSTerminalId' — это ключ? У меня в схеме об этом ни слова. Но на этом приколы не заканчиваются — если раскомментить Append() и закомментить AddRange(), то добаавление проходит на ура, и на "ключ" оно не жалуется. ЧЯДНТ? И как писать такое правильно?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.