zoukankan      html  css  js  c++  java
  • ABP框架使用(版本3.3.1)

        public class Test : FullAuditedAggregateRootWithUser<Guid, AppUser>
        {
            public string TransactionNumber { get; set; }
    
            public virtual List<TestItem> TestItems { get; set; }
        }
        
        public class TestItem : AuditedEntity
        {
            public Guid TestId { get; set; }
            public Guid ItemId { get; set; }
    
            [ForeignKey("ItemId")]
            public Item Item { get; set; }
            public int Quantity { get; set; }
    
            public virtual List<TestSubItem> TestSubItems { get; set; }
            public override object[] GetKeys()
            {
                return new object[] { TestId,ItemId };
            }
        }
        
            public class TestSubItem : AuditedEntity
        {
            public Guid TestId { get; set; }
            public Guid ItemId { get; set; }
    
            [ForeignKey("TierId")]
            public Tier Tier { get; set; }
            public Guid TierId { get; set; }
            public int Quantity { get; set; }
            public override object[] GetKeys()
            {
                return new object[] { TestId, ItemId , TierId };
            }
        }

    1.当update TestItem的值 , 使用updateaync会报错

    2021-03-27 18:51:43.422 +08:00 [ERR] The instance of entity type 'TestSubItem' cannot be tracked because another instance with the same key value for {'TestId', 'ItemId', 'SubItemId'} 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.

    研究了好久,找不到方法override 这个类 StateManager.

    用下面改变 EntityState 的方法是有时凑效有时不凑效

    _context.Attach(modelPostedToController);
    IEnumerable<EntityEntry> unchangedEntities = _context.ChangeTracker.Entries().Where(x => x.State == EntityState.Unchanged);
    foreach(EntityEntry ee in unchangedEntities){
         ee.State = EntityState.Modified;
    }
    await _context.SaveChangesAsync();

    最后的解决方案是先 remove 再 update, 而且一定不能用 DbContext.SaveChangesAsync()

    要是用aynchu会报错

    [ERR] A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.

        public class TestItemRepository : EfCoreRepository<DRSDbContext, TestItem>, ITestItemRepository
        {
    
            public TestItemRepository(IDbContextProvider<DRSDbContext> dbContextProvider) : base(dbContextProvider)
            {
    
            }
    
            public Task Save(List<TestItem> entities)
            {
                DbContext.AttachRange(entities);
                DbContext.UpdateRange(entities);
                DbContext.SaveChanges();
                return Task.CompletedTask;
            }
    
            public Task Remove(List<TestItem> entities)
            {
                DbContext.AttachRange(entities);
                DbContext.RemoveRange(entities);
                DbContext.SaveChanges();
                return Task.CompletedTask;
            }
    
        }

    2.当update sub entity的时候,如果sub entity有soft delete的话就会报duplicate key错。

    sub entity不可以有soft delete,才可以update成功。当做法总是会先删除旧的那条,再新增新的那条。所以从last modify time时间来看是不能正确反映真实情况的。

    在abp没有找到DbContext如何触发到ChangeTracker的代码,翻看了下ef core的源代码,用的ReferenceEquals,无从改造大。

    那么就还是在DbContext对ChangeTracker再做一层过滤,回归到Unchanged和Modified的State.

    DbContext

      protected override EntityChangeReport ApplyAbpConcepts()    
    { var changeReport = new EntityChangeReport(); var addList = ChangeTracker.Entries().Where(o => o.State == EntityState.Added).ToList(); var delList = ChangeTracker.Entries().Where(o => o.State == EntityState.Deleted).ToList(); var addListKeys = addList.Select(o => GetEntityId(o.Entity)).ToList(); var delListKeys = delList.Select(o => GetEntityId(o.Entity)).ToList(); var addListHashCodes = addList.Select(o => o.Entity.GetHashCode()).ToList(); var delListHashCodes = delList.Select(o => o.Entity.GetHashCode()).ToList(); var modListKeys = addListKeys.Intersect(delListKeys); var modListHashCodes = addListHashCodes.Intersect(delListHashCodes); foreach (var entry in ChangeTracker.Entries().ToList()) { var keys = GetEntityId(entry.Entity); var hashCodes = entry.Entity.GetHashCode(); if (entry.State == EntityState.Added && modListHashCodes.Contains(hashCodes)) { entry.State = EntityState.Unchanged; } else if (entry.State == EntityState.Added && modListKeys.Contains(keys)) { entry.State = EntityState.Modified; } if (entry.State == EntityState.Deleted && modListKeys.Contains(keys)) continue; ApplyAbpConcepts(entry, changeReport); } return changeReport; }

    这里因为Added entity 的LastModifyTime和Deleted entity 的LastModifyTime不一致,所以要改写sub entity的GetHashCode() 方法,才能判断出两者是UnChanged

        public class ItemTier : AuditedEntity //FullAuditedEntity
        {
            public Guid ItemId { get; set; }
            
            public Guid TierId { get; set; }
    
            [ForeignKey("ItemId")]
            public virtual Item Item { get; set; }
    
            [ForeignKey("TierId")]
            public /*virtual*/  Tier Tier { get; set; }
    
            public bool Allow { get; set; }
    
            public override object[] GetKeys()
            {
                return new object[] { ItemId, TierId };
            }
    
            public override int GetHashCode()
            {
                unchecked // Overflow is fine, just wrap
                {
                    int hash = 17;
                    // Suitable nullity checks etc, of course :)
                    hash = hash * 23 + ItemId.GetHashCode();
                    hash = hash * 23 + TierId.GetHashCode();
                    hash = hash * 23 + Allow.GetHashCode();
                    return hash;
                }
            }
    
        }
  • 相关阅读:
    wget(转)
    852. Peak Index in a Mountain Array
    617. Merge Two Binary Trees
    814. Binary Tree Pruning
    657. Judge Route Circle
    861. Score After Flipping Matrix
    832. Flipping an Image
    461. Hamming Distance
    654. Maximum Binary Tree
    804. Unique Morse Code Words
  • 原文地址:https://www.cnblogs.com/sui84/p/14587405.html
Copyright © 2011-2022 走看看