- 优化 内部代码 GeTableRef

This commit is contained in:
2881099 2022-09-03 13:13:17 +08:00
parent 6703af3185
commit 074dd7f13d
9 changed files with 154 additions and 55 deletions

View File

@ -715,8 +715,8 @@ namespace FreeSql
List<NativeTuple<TableRef, PropertyInfo>> LocalGetNavigates(TableInfo tb) List<NativeTuple<TableRef, PropertyInfo>> LocalGetNavigates(TableInfo tb)
{ {
return tb.Properties.Where(a => tb.ColumnsByCs.ContainsKey(a.Key) == false) return tb.GetAllTableRef().Where(a => tb.ColumnsByCs.ContainsKey(a.Key) == false && a.Value.Exception == null)
.Select(a => new NativeTuple<TableRef, PropertyInfo>(tb.GetTableRef(a.Key, false), a.Value)) .Select(a => new NativeTuple<TableRef, PropertyInfo>(a.Value, tb.Properties[a.Key]))
.Where(a => a.Item1 != null && new[] { TableRefType.OneToOne, TableRefType.OneToMany, TableRefType.ManyToMany }.Contains(a.Item1.RefType)) .Where(a => a.Item1 != null && new[] { TableRefType.OneToOne, TableRefType.OneToMany, TableRefType.ManyToMany }.Contains(a.Item1.RefType))
.ToList(); .ToList();
} }

View File

@ -800,14 +800,5 @@
<param name="that"></param> <param name="that"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
<summary>
批量注入 Repository可以参考代码自行调整
</summary>
<param name="services"></param>
<param name="globalDataFilter"></param>
<param name="assemblies"></param>
<returns></returns>
</member>
</members> </members>
</doc> </doc>

View File

@ -205,11 +205,11 @@ namespace FreeSql
var table = Orm.CodeFirst.GetTableByEntity(entityType); var table = Orm.CodeFirst.GetTableByEntity(entityType);
if (table == null) return; if (table == null) return;
if (!string.IsNullOrWhiteSpace(navigatePath)) navigatePath = $"{navigatePath}."; 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); var tbref = tr.Value;
if (tbref == null) continue; if (tbref.Exception != null) continue;
var navigateExpression = $"{navigatePath}{prop.Name}"; var navigateExpression = $"{navigatePath}{tr.Key}";
switch (tbref.RefType) switch (tbref.RefType)
{ {
case TableRefType.OneToOne: case TableRefType.OneToOne:
@ -240,11 +240,11 @@ namespace FreeSql
var table = Orm.CodeFirst.GetTableByEntity(entityType); var table = Orm.CodeFirst.GetTableByEntity(entityType);
if (table == null) return null; if (table == null) return null;
if (!string.IsNullOrWhiteSpace(navigatePath)) navigatePath = $"{navigatePath}."; 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); var tbref = tr.Value;
if (tbref == null) continue; if (tbref.Exception != null) continue;
var navigateExpression = $"{navigatePath}{prop.Name}"; var navigateExpression = $"{navigatePath}{tr.Key}";
var depthTab = "".PadLeft(depth * 4); var depthTab = "".PadLeft(depth * 4);
var lambdaAlias = (char)((byte)'a' + (depth - 1)); var lambdaAlias = (char)((byte)'a' + (depth - 1));
var lambdaStr = $"{lambdaAlias} => {lambdaAlias}."; var lambdaStr = $"{lambdaAlias} => {lambdaAlias}.";

View File

@ -91,10 +91,11 @@ namespace FreeSql
localAffrows += ret.Count; localAffrows += ret.Count;
foreach (var entity in entitys) LocalCanAggregateRoot(repository.EntityType, entity, true); 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); var tbref = tr.Value;
if (tbref == null) continue; if (tbref.Exception != null) continue;
if (table.Properties.TryGetValue(tr.Key, out var prop) == false) continue;
switch (tbref.RefType) switch (tbref.RefType)
{ {
case TableRefType.OneToOne: case TableRefType.OneToOne:

View File

@ -74,10 +74,11 @@ static class AggregateRootUtils
if (changes.Any()) if (changes.Any())
updateLog.Add(NativeTuple.Create(entityType, entityBefore, entityAfter, changes)); 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); var tbref = tr.Value;
if (tbref == null) continue; if (tbref.Exception != null) continue;
if (table.Properties.TryGetValue(tr.Key, out var prop) == false) continue;
if (navigatePropertyName != null && prop.Name != navigatePropertyName) continue; if (navigatePropertyName != null && prop.Name != navigatePropertyName) continue;
var propvalBefore = table.GetPropertyValue(entityBefore, prop.Name); var propvalBefore = table.GetPropertyValue(entityBefore, prop.Name);
var propvalAfter = table.GetPropertyValue(entityAfter, prop.Name); var propvalAfter = table.GetPropertyValue(entityAfter, prop.Name);
@ -189,10 +190,11 @@ static class AggregateRootUtils
if (stateKeys.ContainsKey(stateKey)) return; if (stateKeys.ContainsKey(stateKey)) return;
stateKeys.Add(stateKey, true); stateKeys.Add(stateKey, true);
foreach (var prop in table.Properties.Values) foreach (var tr in table.GetAllTableRef())
{ {
var tbref = table.GetTableRef(prop.Name, false); var tbref = tr.Value;
if (tbref == null) continue; if (tbref.Exception != null) continue;
if (table.Properties.TryGetValue(tr.Key, out var prop) == false) continue;
switch (tbref.RefType) switch (tbref.RefType)
{ {
case TableRefType.OneToOne: case TableRefType.OneToOne:

View File

@ -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<Order>
{
public OrderRepository(IFreeSql fsql, UnitOfWorkManager uowManager) : base(uowManager?.Orm ?? fsql)
{
var code = SelectAggregateRootStaticCode;
}
public override ISelect<Order> Select => base.SelectDiy;
}
[Fact]
public void Test1()
{
using (var fsql = g.CreateMemory())
{
new OrderRepository(fsql, null);
var repo = fsql.GetAggregateRootRepository<Order>();
var order = new Order
{
Field2 = "field2",
Extdata = new OrderExt { Field3 = "field3" },
Details = new List<OrderDetail>
{
[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<Tag>().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<OrderDetail> Details { get; set; }
[Navigate(ManyToMany = typeof(OrderTag))]
public List<Tag> 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<Order> Orders { get; set; }
}
}
}

View File

@ -547,10 +547,8 @@ public static partial class FreeSqlGlobalExtensions
{ {
var select = that as Select1Provider<T1>; var select = that as Select1Provider<T1>;
var tb = select._tables[0].Table; var tb = select._tables[0].Table;
var navs = tb.Properties.Select(a => tb.GetTableRef(a.Key, false)) var navs = tb.GetAllTableRef().Where(a => a.Value.Exception == null).Select(a => a.Value)
.Where(a => a != null && .Where(a => a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && a.RefEntityType == tb.Type).ToArray();
a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany &&
a.RefEntityType == tb.Type).ToArray();
var list = select.ToList(); var list = select.ToList();
if (navs.Length != 1) return list; if (navs.Length != 1) return list;
@ -570,10 +568,8 @@ public static partial class FreeSqlGlobalExtensions
{ {
var select = that as Select1Provider<T1>; var select = that as Select1Provider<T1>;
var tb = select._tables[0].Table; var tb = select._tables[0].Table;
var navs = tb.Properties.Select(a => tb.GetTableRef(a.Key, false)) var navs = tb.GetAllTableRef().Where(a => a.Value.Exception == null).Select(a => a.Value)
.Where(a => a != null && .Where(a => a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && a.RefEntityType == tb.Type).ToArray();
a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany &&
a.RefEntityType == tb.Type).ToArray();
var list = await select.ToListAsync(false, cancellationToken); var list = await select.ToListAsync(false, cancellationToken);
if (navs.Length != 1) return list; if (navs.Length != 1) return list;
@ -614,10 +610,8 @@ public static partial class FreeSqlGlobalExtensions
var select = that as Select1Provider<T1>; var select = that as Select1Provider<T1>;
select._is_AsTreeCte = true; select._is_AsTreeCte = true;
var tb = select._tables[0].Table; var tb = select._tables[0].Table;
var navs = tb.Properties.Select(a => tb.GetTableRef(a.Key, false)) var navs = tb.GetAllTableRef().Where(a => a.Value.Exception == null).Select(a => a.Value)
.Where(a => a != null && .Where(a => a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany && a.RefEntityType == tb.Type).ToArray();
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)); if (navs.Length != 1) throw new ArgumentException(CoreStrings.Entity_NotParentChild_Relationship(tb.Type.FullName));
var tbref = navs[0]; var tbref = navs[0];

View File

@ -198,10 +198,11 @@ namespace FreeSql.Internal
} }
if (_tables?.Count > 1) if (_tables?.Count > 1)
{ //如果下级导航属性被 Include 过,则将他们也查询出来 { //如果下级导航属性被 Include 过,则将他们也查询出来
foreach (var memProp in tb.Properties.Values) foreach (var tr in tb.GetAllTableRef())
{ {
var memtbref = tb.GetTableRef(memProp.Name, false); var memtbref = tr.Value;
if (memtbref == null) continue; if (memtbref.Exception != null) continue;
if (tb.Properties.TryGetValue(tr.Key, out var memProp) == false) continue;
switch (memtbref.RefType) switch (memtbref.RefType)
{ {
case TableRefType.ManyToMany: case TableRefType.ManyToMany:

View File

@ -940,16 +940,16 @@ namespace FreeSql.Internal.CommonProvider
} }
} }
var parentNavs = new List<string>(); var parentNavs = new List<string>();
foreach (var navProp in tbref2.Properties) foreach (var tr2 in tbref2.GetAllTableRef())
{ {
if (tbref2.ColumnsByCs.ContainsKey(navProp.Key)) continue; var tr2ref = tr2.Value;
if (tbref2.ColumnsByCsIgnore.ContainsKey(navProp.Key)) continue; if (tr2ref.Exception != null) continue;
var tr2ref = tbref2.GetTableRef(navProp.Key, false); if (tbref2.ColumnsByCs.ContainsKey(tr2.Key)) continue;
if (tr2ref == null) continue; if (tbref2.ColumnsByCsIgnore.ContainsKey(tr2.Key)) continue;
if (tr2ref.RefType != TableRefType.ManyToOne) continue; if (tr2ref.RefType != TableRefType.ManyToOne) continue;
if (tr2ref.RefEntityType != tb.Type) 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 多个相同类型的导航属性值都填充了 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) 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 dicSubList = subList.ToDictionary(a => EntityUtilExtensions.GetEntityValueWithPropertyName(_orm, tbref.RefEntityType, a, tbref.RefColumns[0].CsName)?.ToString(), a => a);
var parentNavs = new List<string>(); var parentNavs = new List<string>();
foreach (var navProp in tbref2.Properties) foreach (var tr2 in tbref2.GetAllTableRef())
{ {
if (tbref2.ColumnsByCs.ContainsKey(navProp.Key)) continue; var tr2ref = tr2.Value;
if (tbref2.ColumnsByCsIgnore.ContainsKey(navProp.Key)) continue; if (tr2ref.Exception != null) continue;
var tr2ref = tbref2.GetTableRef(navProp.Key, false); if (tbref2.ColumnsByCs.ContainsKey(tr2.Key)) continue;
if (tr2ref == null) continue; if (tbref2.ColumnsByCsIgnore.ContainsKey(tr2.Key)) continue;
if (tr2ref.RefType != TableRefType.ManyToOne) continue; if (tr2ref.RefType != TableRefType.ManyToOne) continue;
if (tr2ref.RefEntityType != tb.Type) 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 多个相同类型的导航属性值都填充了 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++) for (var y = 0; y < list.Count; y++)
{ {