diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 3545ffb0..204ebcc5 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -715,8 +715,8 @@ namespace FreeSql List> LocalGetNavigates(TableInfo tb) { - return tb.Properties.Where(a => tb.ColumnsByCs.ContainsKey(a.Key) == false) - .Select(a => new NativeTuple(tb.GetTableRef(a.Key, false), a.Value)) + return tb.GetAllTableRef().Where(a => tb.ColumnsByCs.ContainsKey(a.Key) == false && a.Value.Exception == null) + .Select(a => new NativeTuple(a.Value, tb.Properties[a.Key])) .Where(a => a.Item1 != null && new[] { TableRefType.OneToOne, TableRefType.OneToMany, TableRefType.ManyToMany }.Contains(a.Item1.RefType)) .ToList(); } diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 26522f10..537315e2 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -800,14 +800,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Repository/AggregateRootRepository.cs b/FreeSql.Repository/AggregateRootRepository.cs index 80928cc0..2b921ccb 100644 --- a/FreeSql.Repository/AggregateRootRepository.cs +++ b/FreeSql.Repository/AggregateRootRepository.cs @@ -205,11 +205,11 @@ namespace FreeSql var table = Orm.CodeFirst.GetTableByEntity(entityType); if (table == null) return; if (!string.IsNullOrWhiteSpace(navigatePath)) navigatePath = $"{navigatePath}."; - foreach (var prop in table.Properties.Values) + foreach (var tr in table.GetAllTableRef()) { - var tbref = table.GetTableRef(prop.Name, false); - if (tbref == null) continue; - var navigateExpression = $"{navigatePath}{prop.Name}"; + var tbref = tr.Value; + if (tbref.Exception != null) continue; + var navigateExpression = $"{navigatePath}{tr.Key}"; switch (tbref.RefType) { case TableRefType.OneToOne: @@ -240,11 +240,11 @@ namespace FreeSql var table = Orm.CodeFirst.GetTableByEntity(entityType); if (table == null) return null; if (!string.IsNullOrWhiteSpace(navigatePath)) navigatePath = $"{navigatePath}."; - foreach (var prop in table.Properties.Values) + foreach (var tr in table.GetAllTableRef()) { - var tbref = table.GetTableRef(prop.Name, false); - if (tbref == null) continue; - var navigateExpression = $"{navigatePath}{prop.Name}"; + var tbref = tr.Value; + if (tbref.Exception != null) continue; + var navigateExpression = $"{navigatePath}{tr.Key}"; var depthTab = "".PadLeft(depth * 4); var lambdaAlias = (char)((byte)'a' + (depth - 1)); var lambdaStr = $"{lambdaAlias} => {lambdaAlias}."; diff --git a/FreeSql.Repository/AggregateRootRepositorySync.cs b/FreeSql.Repository/AggregateRootRepositorySync.cs index 669b8f67..fb6ce851 100644 --- a/FreeSql.Repository/AggregateRootRepositorySync.cs +++ b/FreeSql.Repository/AggregateRootRepositorySync.cs @@ -91,10 +91,11 @@ namespace FreeSql localAffrows += ret.Count; foreach (var entity in entitys) LocalCanAggregateRoot(repository.EntityType, entity, true); - foreach (var prop in table.Properties.Values) + foreach (var tr in table.GetAllTableRef()) { - var tbref = table.GetTableRef(prop.Name, false); - if (tbref == null) continue; + 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: diff --git a/FreeSql.Repository/AggregateRootUtils.cs b/FreeSql.Repository/AggregateRootUtils.cs index eb307f99..16e83596 100644 --- a/FreeSql.Repository/AggregateRootUtils.cs +++ b/FreeSql.Repository/AggregateRootUtils.cs @@ -74,10 +74,11 @@ static class AggregateRootUtils if (changes.Any()) updateLog.Add(NativeTuple.Create(entityType, entityBefore, entityAfter, changes)); - foreach (var prop in table.Properties.Values) + foreach (var tr in table.GetAllTableRef()) { - var tbref = table.GetTableRef(prop.Name, false); - if (tbref == null) continue; + var tbref = tr.Value; + if (tbref.Exception != null) continue; + if (table.Properties.TryGetValue(tr.Key, out var prop) == false) continue; if (navigatePropertyName != null && prop.Name != navigatePropertyName) continue; var propvalBefore = table.GetPropertyValue(entityBefore, prop.Name); var propvalAfter = table.GetPropertyValue(entityAfter, prop.Name); @@ -189,10 +190,11 @@ static class AggregateRootUtils if (stateKeys.ContainsKey(stateKey)) return; stateKeys.Add(stateKey, true); - foreach (var prop in table.Properties.Values) + foreach (var tr in table.GetAllTableRef()) { - var tbref = table.GetTableRef(prop.Name, false); - if (tbref == null) continue; + 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: diff --git a/FreeSql.Tests/FreeSql.Tests.DbContext2/AggregateRootRepositoryTest2.cs b/FreeSql.Tests/FreeSql.Tests.DbContext2/AggregateRootRepositoryTest2.cs new file mode 100644 index 00000000..81b76972 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.DbContext2/AggregateRootRepositoryTest2.cs @@ -0,0 +1,110 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace FreeSql.Tests.DbContext2 +{ + public class AggregateRootRepositoryTest2 + { + class OrderRepository : AggregateRootRepository + { + public OrderRepository(IFreeSql fsql, UnitOfWorkManager uowManager) : base(uowManager?.Orm ?? fsql) + { + var code = SelectAggregateRootStaticCode; + } + + public override ISelect Select => base.SelectDiy; + } + + [Fact] + public void Test1() + { + using (var fsql = g.CreateMemory()) + { + new OrderRepository(fsql, null); + + var repo = fsql.GetAggregateRootRepository(); + var order = new Order + { + Field2 = "field2", + Extdata = new OrderExt { Field3 = "field3" }, + Details = new List + { + [0] = new OrderDetail { Field4 = "field4_01", Extdata = new OrderDetailExt { Field5 = "field5_01" } }, + [0] = new OrderDetail { Field4 = "field4_02", Extdata = new OrderDetailExt { Field5 = "field5_02" } }, + [0] = new OrderDetail { Field4 = "field4_03", Extdata = new OrderDetailExt { Field5 = "field5_03" } }, + }, + Tags = fsql.Select().Where(a => new[] { 1, 2, 3 }.Contains(a.Id)).ToList() + }; + repo.Insert(order); //级联插入 + } + } + class Order + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Field2 { get; set; } + + [Navigate(nameof(Id))] + public OrderExt Extdata { get; set; } + [Navigate(nameof(OrderDetail.OrderId))] + public List Details { get; set; } + [Navigate(ManyToMany = typeof(OrderTag))] + public List Tags { get; set; } + } + class OrderExt + { + [Key] + public int OrderId { get; set; } + public string Field3 { get; set; } + + [Navigate(nameof(OrderId))] + public Order Order { get; set; } + } + class OrderDetail + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int OrderId { get; set; } + public string Field4 { get; set; } + + [Navigate(nameof(Id))] + public OrderDetailExt Extdata { get; set; } + } + class OrderDetailExt + { + [Key] + public int OrderDetailId { get; set; } + public string Field5 { get; set; } + + [Navigate(nameof(OrderDetailId))] + public OrderDetail OrderDetail { get; set; } + } + class OrderTag + { + [Key] + public int OrderId { get; set; } + [Key] + public int TagId { get; set; } + + [Navigate(nameof(OrderId))] + public Order Order { get; set; } + [Navigate(nameof(TagId))] + public Tag Tag { get; set; } + } + class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Name { get; set; } + + [Navigate(ManyToMany = typeof(Order))] + public List Orders { get; set; } + } + } +} diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index 3522ebcf..8d2c97d5 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -547,10 +547,8 @@ public static partial class FreeSqlGlobalExtensions { var select = that as Select1Provider; var tb = select._tables[0].Table; - var navs = tb.Properties.Select(a => tb.GetTableRef(a.Key, false)) - .Where(a => a != null && - a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && - a.RefEntityType == tb.Type).ToArray(); + var navs = tb.GetAllTableRef().Where(a => a.Value.Exception == null).Select(a => a.Value) + .Where(a => a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && a.RefEntityType == tb.Type).ToArray(); var list = select.ToList(); if (navs.Length != 1) return list; @@ -570,10 +568,8 @@ public static partial class FreeSqlGlobalExtensions { var select = that as Select1Provider; var tb = select._tables[0].Table; - var navs = tb.Properties.Select(a => tb.GetTableRef(a.Key, false)) - .Where(a => a != null && - a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && - a.RefEntityType == tb.Type).ToArray(); + var navs = tb.GetAllTableRef().Where(a => a.Value.Exception == null).Select(a => a.Value) + .Where(a => a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && a.RefEntityType == tb.Type).ToArray(); var list = await select.ToListAsync(false, cancellationToken); if (navs.Length != 1) return list; @@ -614,10 +610,8 @@ public static partial class FreeSqlGlobalExtensions var select = that as Select1Provider; select._is_AsTreeCte = true; var tb = select._tables[0].Table; - var navs = tb.Properties.Select(a => tb.GetTableRef(a.Key, false)) - .Where(a => a != null && - a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && - a.RefEntityType == tb.Type).ToArray(); + var navs = tb.GetAllTableRef().Where(a => a.Value.Exception == null).Select(a => a.Value) + .Where(a => a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && a.RefEntityType == tb.Type).ToArray(); if (navs.Length != 1) throw new ArgumentException(CoreStrings.Entity_NotParentChild_Relationship(tb.Type.FullName)); var tbref = navs[0]; diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 6ede7538..ebdf6917 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -198,10 +198,11 @@ namespace FreeSql.Internal } if (_tables?.Count > 1) { //如果下级导航属性被 Include 过,则将他们也查询出来 - foreach (var memProp in tb.Properties.Values) + foreach (var tr in tb.GetAllTableRef()) { - var memtbref = tb.GetTableRef(memProp.Name, false); - if (memtbref == null) continue; + var memtbref = tr.Value; + if (memtbref.Exception != null) continue; + if (tb.Properties.TryGetValue(tr.Key, out var memProp) == false) continue; switch (memtbref.RefType) { case TableRefType.ManyToMany: diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index bee3707a..87e67899 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -940,16 +940,16 @@ namespace FreeSql.Internal.CommonProvider } } var parentNavs = new List(); - foreach (var navProp in tbref2.Properties) + foreach (var tr2 in tbref2.GetAllTableRef()) { - if (tbref2.ColumnsByCs.ContainsKey(navProp.Key)) continue; - if (tbref2.ColumnsByCsIgnore.ContainsKey(navProp.Key)) continue; - var tr2ref = tbref2.GetTableRef(navProp.Key, false); - if (tr2ref == null) continue; + var tr2ref = tr2.Value; + if (tr2ref.Exception != null) continue; + if (tbref2.ColumnsByCs.ContainsKey(tr2.Key)) continue; + if (tbref2.ColumnsByCsIgnore.ContainsKey(tr2.Key)) continue; if (tr2ref.RefType != TableRefType.ManyToOne) continue; if (tr2ref.RefEntityType != tb.Type) continue; if (string.Join(",", tr2ref.Columns.Select(a => a.CsName).OrderBy(a => a)) != string.Join(",", tbref.RefColumns.Select(a => a.CsName).OrderBy(a => a))) continue; //- 修复 IncludeMany 只填充子属性中双向关系的 ManyToOne 对象值;防止把 ManyToOne 多个相同类型的导航属性值都填充了 - parentNavs.Add(navProp.Key); + parentNavs.Add(tr2.Key); } foreach (var nav in subList) { @@ -1366,16 +1366,16 @@ namespace FreeSql.Internal.CommonProvider var dicSubList = subList.ToDictionary(a => EntityUtilExtensions.GetEntityValueWithPropertyName(_orm, tbref.RefEntityType, a, tbref.RefColumns[0].CsName)?.ToString(), a => a); var parentNavs = new List(); - foreach (var navProp in tbref2.Properties) + foreach (var tr2 in tbref2.GetAllTableRef()) { - if (tbref2.ColumnsByCs.ContainsKey(navProp.Key)) continue; - if (tbref2.ColumnsByCsIgnore.ContainsKey(navProp.Key)) continue; - var tr2ref = tbref2.GetTableRef(navProp.Key, false); - if (tr2ref == null) continue; + var tr2ref = tr2.Value; + if (tr2ref.Exception != null) continue; + if (tbref2.ColumnsByCs.ContainsKey(tr2.Key)) continue; + if (tbref2.ColumnsByCsIgnore.ContainsKey(tr2.Key)) continue; if (tr2ref.RefType != TableRefType.ManyToOne) continue; if (tr2ref.RefEntityType != tb.Type) continue; if (string.Join(",", tr2ref.Columns.Select(a => a.CsName).OrderBy(a => a)) != string.Join(",", tbref.RefColumns.Select(a => a.CsName).OrderBy(a => a))) continue; //- 修复 IncludeMany 只填充子属性中双向关系的 ManyToOne 对象值;防止把 ManyToOne 多个相同类型的导航属性值都填充了 - parentNavs.Add(navProp.Key); + parentNavs.Add(tr2.Key); } for (var y = 0; y < list.Count; y++) {