diff --git a/FreeSql.Repository/AggregateRootBoundaryAttribute.cs b/FreeSql.Repository/AggregateRootBoundaryAttribute.cs
new file mode 100644
index 00000000..b45601ca
--- /dev/null
+++ b/FreeSql.Repository/AggregateRootBoundaryAttribute.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Linq;
+
+namespace FreeSql.DataAnnotations
+{
+
+    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
+    public class AggregateRootBoundaryAttribute : Attribute
+    {
+        public string Name { get; set; }
+        /// 
+        /// 边界是否终止
+        /// 
+        public bool Break { get; set; }
+        /// 
+        /// 边界是否终止向下探测
+        /// 
+        public bool BreakThen { get; set; }
+
+        public AggregateRootBoundaryAttribute(string name)
+        {
+            this.Name = name;
+        }
+        public AggregateRootBoundaryAttribute()
+        {
+        }
+    }
+}
diff --git a/FreeSql.Repository/AggregateRootRepository.cs b/FreeSql.Repository/AggregateRootRepository.cs
index 59a38c9d..7910b77e 100644
--- a/FreeSql.Repository/AggregateRootRepository.cs
+++ b/FreeSql.Repository/AggregateRootRepository.cs
@@ -1,4 +1,5 @@
 using FreeSql.Extensions.EntityUtil;
+using FreeSql.Internal.Model;
 using System;
 using System.Collections;
 using System.Collections.Generic;
@@ -7,7 +8,12 @@ using System.Linq.Expressions;
 
 namespace FreeSql
 {
-    public partial class AggregateRootRepository : IBaseRepository where TEntity : class
+    public interface IAggregateRootRepository: IBaseRepository where TEntity : class
+    {
+        IBaseRepository ChangeBoundary(string name);
+    }
+
+    public partial class AggregateRootRepository : IAggregateRootRepository where TEntity : class
     {
         readonly IBaseRepository _repository;
         public AggregateRootRepository(IFreeSql fsql)
@@ -23,10 +29,21 @@ namespace FreeSql
         public void Dispose()
         {
             DisposeChildRepositorys();
+            _repository.FlushState();
             _repository.Dispose();
             FlushState();
         }
 
+        string _boundaryName = "";
+        public IBaseRepository ChangeBoundary(string name)
+        {
+            DisposeChildRepositorys();
+            _repository.FlushState();
+            FlushState();
+            _boundaryName = name;
+            return this;
+        }
+
         public IFreeSql Orm => _repository.Orm;
         public IUnitOfWork UnitOfWork { get => _repository.UnitOfWork; set => _repository.UnitOfWork = value; }
         public DbContextOptions DbContextOptions
@@ -61,9 +78,26 @@ namespace FreeSql
                 Attach(item);
         }
         public IBaseRepository AttachOnlyPrimary(TEntity data) => _repository.AttachOnlyPrimary(data);
-        public Dictionary CompareState(TEntity newdata) => _repository.CompareState(newdata);
+        public Dictionary CompareState(TEntity newdata)
+        {
+            if (newdata == null) return null;
+            var _table = Orm.CodeFirst.GetTableByEntity(EntityType);
+            if (_table.Primarys.Any() == false) throw new Exception(DbContextStrings.Incomparable_EntityHasNo_PrimaryKey(Orm.GetEntityString(EntityType, newdata)));
+            var key = Orm.GetEntityKeyString(EntityType, newdata, false);
+            if (string.IsNullOrEmpty(key)) throw new Exception(DbContextStrings.Incomparable_PrimaryKey_NotSet(Orm.GetEntityString(EntityType, newdata)));
+            if (_states.TryGetValue(key, out var oldState) == false || oldState == null) throw new Exception($"不可对比,数据未被跟踪:{Orm.GetEntityString(EntityType, newdata)}");
+            AggregateRootTrackingChangeInfo tracking = new AggregateRootTrackingChangeInfo();
+            AggregateRootUtils.CompareEntityValue(_boundaryName, Orm, EntityType, oldState, newdata, null, tracking);
+            return new Dictionary
+            {
+                ["Insert"] = tracking.InsertLog.Select(a => new object[] { a.Item1, a.Item2 }).ToArray(),
+                ["Delete"] = tracking.DeleteLog.Select(a => new object[] { a.Item1, a.Item2 }).ToArray(),
+                ["Update"] = tracking.UpdateLog.Select(a => new object[] { a.Item1, a.Item2, a.Item3, a.Item4 }).ToArray(),
+            };
+        }
         public void FlushState()
         {
+            DisposeChildRepositorys();
             _repository.FlushState();
             _states.Clear();
         }
@@ -117,7 +151,7 @@ namespace FreeSql
             if (data == null) throw new ArgumentNullException(nameof(data));
             var key = Orm.GetEntityKeyString(EntityType, data, false);
             var state = new EntityState((TEntity)EntityType.CreateInstanceGetDefaultValue(), key);
-            AggregateRootUtils.MapEntityValue(Orm, EntityType, data, state.Value);
+            AggregateRootUtils.MapEntityValue(_boundaryName, Orm, EntityType, data, state.Value);
             return state;
         }
         bool? ExistsInStates(object data)
@@ -139,9 +173,9 @@ namespace FreeSql
         /// 创建查询对象(纯净)
         /// _
         /// 聚合根内关系较复杂时,获取 Include/IncludeMany 字符串代码,方便二次开发
-        /// string code = AggregateRootUtils.GetAutoIncludeQueryStaicCode(fsql, typeof(Order))
+        /// string code = AggregateRootUtils.GetAutoIncludeQueryStaicCode(null, fsql, typeof(Order))
         /// 
-        protected ISelect SelectDiy => _repository.Select;
+        protected ISelect SelectDiy => _repository.Select.TrackToList(SelectAggregateRootTracking);
         /// 
         /// 创建查询对象(递归包含 Include/IncludeMany 边界之内的导航属性)
         /// 
@@ -151,7 +185,7 @@ namespace FreeSql
             get
             {
                 var query = _repository.Select.TrackToList(SelectAggregateRootTracking);
-                query = AggregateRootUtils.GetAutoIncludeQuery(query);
+                query = AggregateRootUtils.GetAutoIncludeQuery(_boundaryName, query);
                 return query;
             }
         }
@@ -214,7 +248,8 @@ namespace FreeSql
         //                currentQuery.IncludeByPropertyName(navigateExpression);
         //                break;
         //            case TableRefType.PgArrayToMany:
-        //            case TableRefType.ManyToOne: //不属于聚合根
+        //                break;
+        //            case TableRefType.ManyToOne:
         //                break;
         //        }
         //    }
diff --git a/FreeSql.Repository/AggregateRootRepositoryAsync.cs b/FreeSql.Repository/AggregateRootRepositoryAsync.cs
index 1ecd4798..f6a94d82 100644
--- a/FreeSql.Repository/AggregateRootRepositoryAsync.cs
+++ b/FreeSql.Repository/AggregateRootRepositoryAsync.cs
@@ -25,7 +25,7 @@ namespace FreeSql
             var repos = new Dictionary();
             try
             {
-                var ret = await InsertWithinBoundaryStaticAsync(_repository, GetChildRepository, entitys, out var affrows, cancellationToken);
+                var ret = await InsertWithinBoundaryStaticAsync(_boundaryName, _repository, GetChildRepository, entitys, out var affrows, cancellationToken);
                 Attach(ret);
                 return ret;
             }
@@ -35,112 +35,9 @@ namespace FreeSql
                 _repository.FlushState();
             }
         }
-        Task> InsertWithinBoundaryStaticAsync(IBaseRepository rootRepository, Func> getChildRepository, IEnumerable rootEntitys, out int affrows, CancellationToken cancellationToken) where T1 : class
+        Task> InsertWithinBoundaryStaticAsync(string boundaryName, IBaseRepository rootRepository, Func> getChildRepository, IEnumerable rootEntitys, out int affrows, CancellationToken cancellationToken) where T1 : class
         {
-            Dictionary> ignores = new Dictionary>();
-            Dictionary> repos = new Dictionary>();
-            var localAffrows = 0;
-            try
-            {
-                return LocalInsertAsync(rootRepository, rootEntitys);
-            }
-            finally
-            {
-                affrows = localAffrows;
-            }
-
-            bool LocalCanInsert(Type entityType, object entity, bool isadd)
-            {
-                var stateKey = rootRepository.Orm.GetEntityKeyString(entityType, entity, false);
-                if (stateKey == null) return true;
-                if (ignores.TryGetValue(entityType, out var stateKeys) == false)
-                {
-                    if (isadd)
-                    {
-                        ignores.Add(entityType, stateKeys = new Dictionary());
-                        stateKeys.Add(stateKey, true);
-                    }
-                    return true;
-                }
-                if (stateKeys.ContainsKey(stateKey) == false)
-                {
-                    if (isadd) stateKeys.Add(stateKey, true);
-                    return true;
-                }
-                return false;
-            }
-            async Task> LocalInsertAsync(IBaseRepository repository, IEnumerable entitys) where T2 : class
-            {
-                var table = repository.Orm.CodeFirst.GetTableByEntity(repository.EntityType);
-                if (table.Primarys.Any(col => col.Attribute.IsIdentity))
-                {
-                    foreach (var entity in entitys)
-                        repository.Orm.ClearEntityPrimaryValueWithIdentity(repository.EntityType, entity);
-                }
-                var ret = await repository.InsertAsync(entitys, cancellationToken);
-                localAffrows += ret.Count;
-                foreach (var entity in entitys) LocalCanInsert(repository.EntityType, entity, true);
-
-                foreach (var tr in table.GetAllTableRef().OrderBy(a => a.Value.RefType).ThenBy(a => a.Key))
-                {
-                    var tbref = tr.Value;
-                    if (tbref.Exception != null) continue;
-                    if (table.Properties.TryGetValue(tr.Key, out var prop) == false) continue;
-                    switch (tbref.RefType)
-                    {
-                        case TableRefType.OneToOne:
-                            var otoList = ret.Select(entity =>
-                            {
-                                var otoItem = table.GetPropertyValue(entity, prop.Name);
-                                if (LocalCanInsert(tbref.RefEntityType, otoItem, false) == false) return null;
-                                AggregateRootUtils.SetNavigateRelationshipValue(repository.Orm, tbref, table.Type, entity, otoItem);
-                                return otoItem;
-                            }).Where(entity => entity != null).ToArray();
-                            if (otoList.Any())
-                            {
-                                var repo = getChildRepository(tbref.RefEntityType);
-                                await LocalInsertAsync(repo, otoList);
-                            }
-                            break;
-                        case TableRefType.OneToMany:
-                            var otmList = ret.Select(entity =>
-                            {
-                                var otmEach = table.GetPropertyValue(entity, prop.Name) as IEnumerable;
-                                if (otmEach == null) return null;
-                                var otmItems = new List