mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
AggregateRootRepository
This commit is contained in:
parent
074dd7f13d
commit
9180375a2b
@ -800,5 +800,14 @@
|
|||||||
<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>
|
||||||
|
@ -1,16 +1,9 @@
|
|||||||
using FreeSql.Extensions.EntityUtil;
|
using FreeSql.Extensions.EntityUtil;
|
||||||
using FreeSql.Internal;
|
|
||||||
using FreeSql.Internal.Model;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace FreeSql
|
namespace FreeSql
|
||||||
{
|
{
|
||||||
@ -156,7 +149,7 @@ namespace FreeSql
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
var query = _repository.Select.TrackToList(SelectAggregateRootTracking);
|
var query = _repository.Select.TrackToList(SelectAggregateRootTracking);
|
||||||
SelectAggregateRootNavigateReader(query, EntityType, "", new Stack<Type>());
|
query = AggregateRootUtils.GetAutoIncludeQuery(query);
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,7 +159,7 @@ namespace FreeSql
|
|||||||
/// 2、返回的内容用,可用于配合重写仓储 override Select 属性<para></para>
|
/// 2、返回的内容用,可用于配合重写仓储 override Select 属性<para></para>
|
||||||
/// 返回内容:fsql.Select<T>().Include(...).IncludeMany(...)
|
/// 返回内容:fsql.Select<T>().Include(...).IncludeMany(...)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected string SelectAggregateRootStaticCode => $"//fsql.Select<{EntityType.Name}>()\r\nthis.SelectDiy{SelectAggregateRootNavigateReader(1, EntityType, "", new Stack<Type>())}";
|
protected string SelectAggregateRootStaticCode => $"//fsql.Select<{EntityType.Name}>()\r\nthis.SelectDiy{AggregateRootUtils.GetAutoIncludeQueryStaicCode(Orm, EntityType)}";
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ISelect.TrackToList 委托,数据返回后自动 Attach
|
/// ISelect.TrackToList 委托,数据返回后自动 Attach
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -198,83 +191,40 @@ namespace FreeSql
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void SelectAggregateRootNavigateReader<T1>(ISelect<T1> currentQuery, Type entityType, string navigatePath, Stack<Type> ignores)
|
//void SelectAggregateRootNavigateReader<T1>(ISelect<T1> currentQuery, Type entityType, string navigatePath, Stack<Type> ignores)
|
||||||
{
|
//{
|
||||||
if (ignores.Any(a => a == entityType)) return;
|
// if (ignores.Any(a => a == entityType)) return;
|
||||||
ignores.Push(entityType);
|
// ignores.Push(entityType);
|
||||||
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 tr in table.GetAllTableRef())
|
// foreach (var tr in table.GetAllTableRef())
|
||||||
{
|
// {
|
||||||
var tbref = tr.Value;
|
// var tbref = tr.Value;
|
||||||
if (tbref.Exception != null) continue;
|
// if (tbref.Exception != null) continue;
|
||||||
var navigateExpression = $"{navigatePath}{tr.Key}";
|
// var navigateExpression = $"{navigatePath}{tr.Key}";
|
||||||
switch (tbref.RefType)
|
// switch (tbref.RefType)
|
||||||
{
|
// {
|
||||||
case TableRefType.OneToOne:
|
// case TableRefType.OneToOne:
|
||||||
if (ignores.Any(a => a == tbref.RefEntityType)) break;
|
// if (ignores.Any(a => a == tbref.RefEntityType)) break;
|
||||||
currentQuery.IncludeByPropertyName(navigateExpression);
|
// currentQuery.IncludeByPropertyName(navigateExpression);
|
||||||
SelectAggregateRootNavigateReader(currentQuery, tbref.RefEntityType, navigateExpression, ignores);
|
// SelectAggregateRootNavigateReader(currentQuery, tbref.RefEntityType, navigateExpression, ignores);
|
||||||
break;
|
// break;
|
||||||
case TableRefType.OneToMany:
|
// case TableRefType.OneToMany:
|
||||||
var ignoresCopy = new Stack<Type>(ignores.ToArray());
|
// var ignoresCopy = new Stack<Type>(ignores.ToArray());
|
||||||
currentQuery.IncludeByPropertyName(navigateExpression, then =>
|
// currentQuery.IncludeByPropertyName(navigateExpression, then =>
|
||||||
SelectAggregateRootNavigateReader(then, tbref.RefEntityType, "", ignoresCopy));
|
// SelectAggregateRootNavigateReader(then, tbref.RefEntityType, "", ignoresCopy)); //variable 'then' of type 'FreeSql.ISelect`1[System.Object]' referenced from scope '', but it is not defined
|
||||||
break;
|
// break;
|
||||||
case TableRefType.ManyToMany:
|
// case TableRefType.ManyToMany:
|
||||||
currentQuery.IncludeByPropertyName(navigateExpression);
|
// currentQuery.IncludeByPropertyName(navigateExpression);
|
||||||
break;
|
// break;
|
||||||
case TableRefType.PgArrayToMany:
|
// case TableRefType.PgArrayToMany:
|
||||||
case TableRefType.ManyToOne: //不属于聚合根
|
// case TableRefType.ManyToOne: //不属于聚合根
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
ignores.Pop();
|
// ignores.Pop();
|
||||||
}
|
//}
|
||||||
string SelectAggregateRootNavigateReader(int depth, Type entityType, string navigatePath, Stack<Type> ignores)
|
|
||||||
{
|
|
||||||
var code = new StringBuilder();
|
|
||||||
if (ignores.Any(a => a == entityType)) return null;
|
|
||||||
ignores.Push(entityType);
|
|
||||||
var table = Orm.CodeFirst.GetTableByEntity(entityType);
|
|
||||||
if (table == null) return null;
|
|
||||||
if (!string.IsNullOrWhiteSpace(navigatePath)) navigatePath = $"{navigatePath}.";
|
|
||||||
foreach (var tr in table.GetAllTableRef())
|
|
||||||
{
|
|
||||||
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}.";
|
|
||||||
switch (tbref.RefType)
|
|
||||||
{
|
|
||||||
case TableRefType.OneToOne:
|
|
||||||
if (ignores.Any(a => a == tbref.RefEntityType)) break;
|
|
||||||
code.Append("\r\n").Append(depthTab).Append(".Include(").Append(lambdaStr).Append(navigateExpression).Append(")");
|
|
||||||
code.Append(SelectAggregateRootNavigateReader(depth, tbref.RefEntityType, navigateExpression, ignores));
|
|
||||||
break;
|
|
||||||
case TableRefType.OneToMany:
|
|
||||||
code.Append("\r\n").Append(depthTab).Append(".IncludeMany(").Append(lambdaStr).Append(navigateExpression);
|
|
||||||
var thencode = SelectAggregateRootNavigateReader(depth + 1, tbref.RefEntityType, "", new Stack<Type>(ignores.ToArray()));
|
|
||||||
if (thencode.Length > 0) code.Append(", then => then").Append(thencode);
|
|
||||||
code.Append(")");
|
|
||||||
break;
|
|
||||||
case TableRefType.ManyToMany:
|
|
||||||
code.Append("\r\n").Append(depthTab).Append(".IncludeMany(").Append(lambdaStr).Append(navigateExpression).Append(")");
|
|
||||||
break;
|
|
||||||
case TableRefType.PgArrayToMany:
|
|
||||||
code.Append("\r\n//").Append(depthTab).Append(".IncludeMany(").Append(lambdaStr).Append(navigateExpression).Append(")");
|
|
||||||
break;
|
|
||||||
case TableRefType.ManyToOne: //不属于聚合根
|
|
||||||
code.Append("\r\n//").Append(depthTab).Append(".Include(").Append(lambdaStr).Append(navigateExpression).Append(")");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ignores.Pop();
|
|
||||||
return code.ToString();
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using FreeSql;
|
using FreeSql;
|
||||||
using FreeSql.Extensions.EntityUtil;
|
using FreeSql.Extensions.EntityUtil;
|
||||||
using FreeSql.Internal;
|
using FreeSql.Internal;
|
||||||
|
using FreeSql.Internal.CommonProvider;
|
||||||
using FreeSql.Internal.Model;
|
using FreeSql.Internal.Model;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
@ -8,7 +9,9 @@ using System.Collections.Concurrent;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
static class AggregateRootUtils
|
static class AggregateRootUtils
|
||||||
{
|
{
|
||||||
@ -85,13 +88,13 @@ static class AggregateRootUtils
|
|||||||
switch (tbref.RefType)
|
switch (tbref.RefType)
|
||||||
{
|
{
|
||||||
case TableRefType.OneToOne:
|
case TableRefType.OneToOne:
|
||||||
SetNavigateRelationshipValue(fsql, tbref, tbref.RefEntityType, entityBefore, propvalBefore);
|
SetNavigateRelationshipValue(fsql, tbref, table.Type, entityBefore, propvalBefore);
|
||||||
SetNavigateRelationshipValue(fsql, tbref, tbref.RefEntityType, entityAfter, propvalAfter);
|
SetNavigateRelationshipValue(fsql, tbref, table.Type, entityAfter, propvalAfter);
|
||||||
LocalCompareEntityValue(tbref.RefEntityType, propvalBefore, propvalAfter, null);
|
LocalCompareEntityValue(tbref.RefEntityType, propvalBefore, propvalAfter, null);
|
||||||
break;
|
break;
|
||||||
case TableRefType.OneToMany:
|
case TableRefType.OneToMany:
|
||||||
SetNavigateRelationshipValue(fsql, tbref, tbref.RefEntityType, entityBefore, propvalBefore);
|
SetNavigateRelationshipValue(fsql, tbref, table.Type, entityBefore, propvalBefore);
|
||||||
SetNavigateRelationshipValue(fsql, tbref, tbref.RefEntityType, entityAfter, propvalAfter);
|
SetNavigateRelationshipValue(fsql, tbref, table.Type, entityAfter, propvalAfter);
|
||||||
LocalCompareEntityValueCollection(tbref, propvalBefore as IEnumerable, propvalAfter as IEnumerable);
|
LocalCompareEntityValueCollection(tbref, propvalBefore as IEnumerable, propvalAfter as IEnumerable);
|
||||||
break;
|
break;
|
||||||
case TableRefType.ManyToMany:
|
case TableRefType.ManyToMany:
|
||||||
@ -201,7 +204,7 @@ static class AggregateRootUtils
|
|||||||
var propval = table.GetPropertyValue(entity, prop.Name);
|
var propval = table.GetPropertyValue(entity, prop.Name);
|
||||||
statckPath.Push(prop.Name);
|
statckPath.Push(prop.Name);
|
||||||
stackValues.Add(propval);
|
stackValues.Add(propval);
|
||||||
SetNavigateRelationshipValue(fsql, tbref, tbref.RefEntityType, entity, propval);
|
SetNavigateRelationshipValue(fsql, tbref, table.Type, entity, propval);
|
||||||
callback?.Invoke(string.Join(".", statckPath), tbref, tbref.RefEntityType, stackValues);
|
callback?.Invoke(string.Join(".", statckPath), tbref, tbref.RefEntityType, stackValues);
|
||||||
LocalNavigateReader(tbref.RefEntityType, propval);
|
LocalNavigateReader(tbref.RefEntityType, propval);
|
||||||
stackValues.RemoveAt(stackValues.Count - 1);
|
stackValues.RemoveAt(stackValues.Count - 1);
|
||||||
@ -209,7 +212,7 @@ static class AggregateRootUtils
|
|||||||
break;
|
break;
|
||||||
case TableRefType.OneToMany:
|
case TableRefType.OneToMany:
|
||||||
var propvalOtm = table.GetPropertyValue(entity, prop.Name);
|
var propvalOtm = table.GetPropertyValue(entity, prop.Name);
|
||||||
SetNavigateRelationshipValue(fsql, tbref, tbref.RefEntityType, entity, propvalOtm);
|
SetNavigateRelationshipValue(fsql, tbref, table.Type, entity, propvalOtm);
|
||||||
var propvalOtmList = new List<object>();
|
var propvalOtmList = new List<object>();
|
||||||
foreach (var val in propvalOtm as IEnumerable)
|
foreach (var val in propvalOtm as IEnumerable)
|
||||||
propvalOtmList.Add(val);
|
propvalOtmList.Add(val);
|
||||||
@ -275,12 +278,12 @@ static class AggregateRootUtils
|
|||||||
{
|
{
|
||||||
case TableRefType.OneToOne:
|
case TableRefType.OneToOne:
|
||||||
var propvalTo = tbref.RefEntityType.CreateInstanceGetDefaultValue();
|
var propvalTo = tbref.RefEntityType.CreateInstanceGetDefaultValue();
|
||||||
SetNavigateRelationshipValue(fsql, tbref, tbref.RefEntityType, entityFrom, propvalFrom);
|
SetNavigateRelationshipValue(fsql, tbref, table.Type, entityFrom, propvalFrom);
|
||||||
LocalMapEntityValue(tbref.RefEntityType, propvalFrom, propvalTo);
|
LocalMapEntityValue(tbref.RefEntityType, propvalFrom, propvalTo);
|
||||||
EntityUtilExtensions.SetEntityValueWithPropertyName(fsql, entityType, entityTo, prop.Name, propvalTo);
|
EntityUtilExtensions.SetEntityValueWithPropertyName(fsql, entityType, entityTo, prop.Name, propvalTo);
|
||||||
break;
|
break;
|
||||||
case TableRefType.OneToMany:
|
case TableRefType.OneToMany:
|
||||||
SetNavigateRelationshipValue(fsql, tbref, tbref.RefEntityType, entityFrom, propvalFrom);
|
SetNavigateRelationshipValue(fsql, tbref, table.Type, entityFrom, propvalFrom);
|
||||||
LocalMapEntityValueCollection(entityType, entityFrom, entityTo, tbref, propvalFrom as IEnumerable, prop, true);
|
LocalMapEntityValueCollection(entityType, entityFrom, entityTo, tbref, propvalFrom as IEnumerable, prop, true);
|
||||||
break;
|
break;
|
||||||
case TableRefType.ManyToMany:
|
case TableRefType.ManyToMany:
|
||||||
@ -315,6 +318,127 @@ static class AggregateRootUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ConcurrentDictionary<Type, ConcurrentDictionary<Type, Action<ISelect0>>> _dicGetAutoIncludeQuery = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, Action<ISelect0>>>();
|
||||||
|
public static ISelect<TEntity> GetAutoIncludeQuery<TEntity>(ISelect<TEntity> select)
|
||||||
|
{
|
||||||
|
var select0p = select as Select0Provider;
|
||||||
|
var table0Type = select0p._tables[0].Table.Type;
|
||||||
|
var func = _dicGetAutoIncludeQuery.GetOrAdd(typeof(TEntity), t => new ConcurrentDictionary<Type, Action<ISelect0>>()).GetOrAdd(table0Type, t =>
|
||||||
|
{
|
||||||
|
var parmExp1 = Expression.Parameter(typeof(ISelect0));
|
||||||
|
var parmNavigateParameterExp = Expression.Parameter(typeof(TEntity), "a");
|
||||||
|
var parmQueryExp = Expression.Convert(parmExp1, typeof(ISelect<>).MakeGenericType(typeof(TEntity)));
|
||||||
|
var exp = LocalGetAutoIncludeQuery(parmQueryExp, 1, t, parmNavigateParameterExp, parmNavigateParameterExp, new Stack<Type>());
|
||||||
|
return Expression.Lambda<Action<ISelect0>>(exp, parmExp1).Compile();
|
||||||
|
});
|
||||||
|
func(select);
|
||||||
|
return select;
|
||||||
|
Expression LocalGetAutoIncludeQuery(Expression queryExp, int depth, Type entityType, ParameterExpression navigateParameterExp, Expression navigatePathExp, Stack<Type> ignores)
|
||||||
|
{
|
||||||
|
if (ignores.Any(a => a == entityType)) return queryExp;
|
||||||
|
ignores.Push(entityType);
|
||||||
|
var table = select0p._orm.CodeFirst.GetTableByEntity(entityType);
|
||||||
|
if (table == null) return queryExp;
|
||||||
|
foreach (var tr in table.GetAllTableRef())
|
||||||
|
{
|
||||||
|
var tbref = tr.Value;
|
||||||
|
if (tbref.Exception != null) continue;
|
||||||
|
if (table.Properties.TryGetValue(tr.Key, out var prop) == false) continue;
|
||||||
|
Expression navigateExp = Expression.MakeMemberAccess(navigatePathExp, prop);
|
||||||
|
//var lambdaAlias = (char)((byte)'a' + (depth - 1));
|
||||||
|
switch (tbref.RefType)
|
||||||
|
{
|
||||||
|
case TableRefType.OneToOne:
|
||||||
|
if (ignores.Any(a => a == tbref.RefEntityType)) break;
|
||||||
|
LocalInclude(tbref, navigateExp);
|
||||||
|
queryExp = LocalGetAutoIncludeQuery(queryExp, depth, tbref.RefEntityType, navigateParameterExp, navigateExp, ignores);
|
||||||
|
break;
|
||||||
|
case TableRefType.OneToMany:
|
||||||
|
LocalIncludeMany(tbref, navigateExp, true);
|
||||||
|
break;
|
||||||
|
case TableRefType.ManyToMany:
|
||||||
|
LocalIncludeMany(tbref, navigateExp, false);
|
||||||
|
break;
|
||||||
|
case TableRefType.PgArrayToMany:
|
||||||
|
break;
|
||||||
|
case TableRefType.ManyToOne: //不属于聚合根
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ignores.Pop();
|
||||||
|
return queryExp;
|
||||||
|
void LocalInclude(TableRef tbref, Expression exp)
|
||||||
|
{
|
||||||
|
var incMethod = queryExp.Type.GetMethod("Include");
|
||||||
|
if (incMethod == null) throw new Exception(CoreStrings.RunTimeError_Reflection_IncludeMany.Replace("IncludeMany", "Include"));
|
||||||
|
queryExp = Expression.Call(queryExp, incMethod.MakeGenericMethod(tbref.RefEntityType),
|
||||||
|
Expression.Lambda(typeof(Func<,>).MakeGenericType(entityType, tbref.RefEntityType), exp, navigateParameterExp));
|
||||||
|
}
|
||||||
|
void LocalIncludeMany(TableRef tbref, Expression exp, bool isthen)
|
||||||
|
{
|
||||||
|
var funcType = typeof(Func<,>).MakeGenericType(entityType, typeof(IEnumerable<>).MakeGenericType(tbref.RefEntityType));
|
||||||
|
var navigateSelector = Expression.Lambda(funcType, exp, navigateParameterExp);
|
||||||
|
var incMethod = queryExp.Type.GetMethod("IncludeMany");
|
||||||
|
if (incMethod == null) throw new Exception(CoreStrings.RunTimeError_Reflection_IncludeMany);
|
||||||
|
LambdaExpression navigateThen = null;
|
||||||
|
var navigateThenType = typeof(Action<>).MakeGenericType(typeof(ISelect<>).MakeGenericType(tbref.RefEntityType));
|
||||||
|
var thenParameter = Expression.Parameter(typeof(ISelect<>).MakeGenericType(tbref.RefEntityType), "then");
|
||||||
|
Expression paramQueryExp = thenParameter;
|
||||||
|
var paramNavigateParameterExp = Expression.Parameter(tbref.RefEntityType, string.Concat((char)((byte)'a' + (depth - 1))));
|
||||||
|
if (isthen) paramQueryExp = LocalGetAutoIncludeQuery(paramQueryExp, depth + 1, tbref.RefEntityType, paramNavigateParameterExp, paramNavigateParameterExp, ignores);
|
||||||
|
navigateThen = Expression.Lambda(navigateThenType, paramQueryExp, thenParameter);
|
||||||
|
queryExp = Expression.Call(queryExp, incMethod.MakeGenericMethod(tbref.RefEntityType), navigateSelector, navigateThen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static string GetAutoIncludeQueryStaicCode(IFreeSql fsql, Type rootEntityType)
|
||||||
|
{
|
||||||
|
return LocalGetAutoIncludeQueryStaicCode(1, rootEntityType, "", new Stack<Type>());
|
||||||
|
string LocalGetAutoIncludeQueryStaicCode(int depth, Type entityType, string navigatePath, Stack<Type> ignores)
|
||||||
|
{
|
||||||
|
var code = new StringBuilder();
|
||||||
|
if (ignores.Any(a => a == entityType)) return null;
|
||||||
|
ignores.Push(entityType);
|
||||||
|
var table = fsql.CodeFirst.GetTableByEntity(entityType);
|
||||||
|
if (table == null) return null;
|
||||||
|
if (!string.IsNullOrWhiteSpace(navigatePath)) navigatePath = $"{navigatePath}.";
|
||||||
|
foreach (var tr in table.GetAllTableRef())
|
||||||
|
{
|
||||||
|
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}.";
|
||||||
|
switch (tbref.RefType)
|
||||||
|
{
|
||||||
|
case TableRefType.OneToOne:
|
||||||
|
if (ignores.Any(a => a == tbref.RefEntityType)) break;
|
||||||
|
code.Append("\r\n").Append(depthTab).Append(".Include(").Append(lambdaStr).Append(navigateExpression).Append(")");
|
||||||
|
code.Append(LocalGetAutoIncludeQueryStaicCode(depth, tbref.RefEntityType, navigateExpression, ignores));
|
||||||
|
break;
|
||||||
|
case TableRefType.OneToMany:
|
||||||
|
code.Append("\r\n").Append(depthTab).Append(".IncludeMany(").Append(lambdaStr).Append(navigateExpression);
|
||||||
|
var thencode = LocalGetAutoIncludeQueryStaicCode(depth + 1, tbref.RefEntityType, "", new Stack<Type>(ignores.ToArray()));
|
||||||
|
if (thencode.Length > 0) code.Append(", then => then").Append(thencode);
|
||||||
|
code.Append(")");
|
||||||
|
break;
|
||||||
|
case TableRefType.ManyToMany:
|
||||||
|
code.Append("\r\n").Append(depthTab).Append(".IncludeMany(").Append(lambdaStr).Append(navigateExpression).Append(")");
|
||||||
|
break;
|
||||||
|
case TableRefType.PgArrayToMany:
|
||||||
|
code.Append("\r\n//").Append(depthTab).Append(".IncludeMany(").Append(lambdaStr).Append(navigateExpression).Append(")");
|
||||||
|
break;
|
||||||
|
case TableRefType.ManyToOne: //不属于聚合根
|
||||||
|
code.Append("\r\n//").Append(depthTab).Append(".Include(").Append(lambdaStr).Append(navigateExpression).Append(")");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ignores.Pop();
|
||||||
|
return code.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static List<object> GetManyToManyObjects(IFreeSql fsql, TableInfo table, TableRef tbref, object entity, PropertyInfo prop)
|
public static List<object> GetManyToManyObjects(IFreeSql fsql, TableInfo table, TableRef tbref, object entity, PropertyInfo prop)
|
||||||
{
|
{
|
||||||
if (tbref.RefType != TableRefType.ManyToMany) return null;
|
if (tbref.RefType != TableRefType.ManyToMany) return null;
|
||||||
|
@ -28,6 +28,15 @@ namespace FreeSql.Tests.DbContext2
|
|||||||
{
|
{
|
||||||
new OrderRepository(fsql, null);
|
new OrderRepository(fsql, null);
|
||||||
|
|
||||||
|
fsql.Insert(new[]
|
||||||
|
{
|
||||||
|
new Tag { Name = "tag1" },
|
||||||
|
new Tag { Name = "tag2" },
|
||||||
|
new Tag { Name = "tag3" },
|
||||||
|
new Tag { Name = "tag4" },
|
||||||
|
new Tag { Name = "tag5" }
|
||||||
|
}).ExecuteAffrows();
|
||||||
|
|
||||||
var repo = fsql.GetAggregateRootRepository<Order>();
|
var repo = fsql.GetAggregateRootRepository<Order>();
|
||||||
var order = new Order
|
var order = new Order
|
||||||
{
|
{
|
||||||
@ -35,13 +44,37 @@ namespace FreeSql.Tests.DbContext2
|
|||||||
Extdata = new OrderExt { Field3 = "field3" },
|
Extdata = new OrderExt { Field3 = "field3" },
|
||||||
Details = new List<OrderDetail>
|
Details = new List<OrderDetail>
|
||||||
{
|
{
|
||||||
[0] = new OrderDetail { Field4 = "field4_01", Extdata = new OrderDetailExt { Field5 = "field5_01" } },
|
new OrderDetail { Field4 = "field4_01", Extdata = new OrderDetailExt { Field5 = "field5_01" } },
|
||||||
[0] = new OrderDetail { Field4 = "field4_02", Extdata = new OrderDetailExt { Field5 = "field5_02" } },
|
new OrderDetail { Field4 = "field4_02", Extdata = new OrderDetailExt { Field5 = "field5_02" } },
|
||||||
[0] = new OrderDetail { Field4 = "field4_03", Extdata = new OrderDetailExt { Field5 = "field5_03" } },
|
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()
|
Tags = fsql.Select<Tag>().Where(a => new[] { 1, 2, 3 }.Contains(a.Id)).ToList()
|
||||||
};
|
};
|
||||||
repo.Insert(order); //级联插入
|
repo.Insert(order); //级联插入
|
||||||
|
|
||||||
|
var order2 = repo.Select.Where(a => a.Id == a.Id).First();
|
||||||
|
Assert.NotNull(order2);
|
||||||
|
Assert.Equal(order.Id, order2.Id);
|
||||||
|
Assert.Equal(order.Field2, order2.Field2);
|
||||||
|
Assert.NotNull(order2.Extdata);
|
||||||
|
Assert.Equal(order.Extdata.Field3, order2.Extdata.Field3);
|
||||||
|
Assert.NotNull(order2.Details);
|
||||||
|
Assert.Equal(order.Details.Count, order2.Details.Count);
|
||||||
|
Assert.Equal(3, order2.Details.Count);
|
||||||
|
for (var a = 0; a < 3; a++)
|
||||||
|
{
|
||||||
|
Assert.Equal(order.Details[a].Id, order2.Details[a].Id);
|
||||||
|
Assert.Equal(order.Details[a].OrderId, order2.Details[a].OrderId);
|
||||||
|
Assert.Equal(order.Details[a].Field4, order2.Details[a].Field4);
|
||||||
|
Assert.NotNull(order2.Details[a].Extdata);
|
||||||
|
Assert.Equal(order.Details[a].Extdata.Field5, order2.Details[a].Extdata.Field5);
|
||||||
|
}
|
||||||
|
Assert.NotNull(order2.Tags);
|
||||||
|
Assert.Equal(3, order2.Tags.Count);
|
||||||
|
Assert.Equal("tag1", order2.Tags[0].Name);
|
||||||
|
Assert.Equal("tag2", order2.Tags[1].Name);
|
||||||
|
Assert.Equal("tag3", order2.Tags[2].Name);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Order
|
class Order
|
||||||
@ -103,7 +136,7 @@ namespace FreeSql.Tests.DbContext2
|
|||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
[Navigate(ManyToMany = typeof(Order))]
|
[Navigate(ManyToMany = typeof(OrderTag))]
|
||||||
public List<Order> Orders { get; set; }
|
public List<Order> Orders { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,12 +214,12 @@ namespace FreeSql.Extensions.EntityUtil
|
|||||||
var var1Parm = Expression.Variable(entityType);
|
var var1Parm = Expression.Variable(entityType);
|
||||||
var var2Ret = Expression.Variable(typeof(object));
|
var var2Ret = Expression.Variable(typeof(object));
|
||||||
var exps = new List<Expression>(new Expression[] {
|
var exps = new List<Expression>(new Expression[] {
|
||||||
Expression.Assign(var1Parm, Expression.TypeAs(parm1, entityType)),
|
Expression.Assign(var1Parm, Expression.TypeAs(parm1, entityType)),
|
||||||
Expression.Assign(
|
Expression.Assign(
|
||||||
var2Ret,
|
var2Ret,
|
||||||
Expression.Convert(Expression.MakeMemberAccess(var1Parm, table.Properties[pn]), typeof(object))
|
Expression.Convert(Expression.MakeMemberAccess(var1Parm, table.Properties[pn]), typeof(object))
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
exps.AddRange(new Expression[] {
|
exps.AddRange(new Expression[] {
|
||||||
Expression.Return(returnTarget, var2Ret),
|
Expression.Return(returnTarget, var2Ret),
|
||||||
Expression.Label(returnTarget, Expression.Default(typeof(object)))
|
Expression.Label(returnTarget, Expression.Default(typeof(object)))
|
||||||
@ -242,12 +242,12 @@ namespace FreeSql.Extensions.EntityUtil
|
|||||||
var var1Parm = Expression.Variable(table.Type);
|
var var1Parm = Expression.Variable(table.Type);
|
||||||
var var2Ret = Expression.Variable(typeof(object));
|
var var2Ret = Expression.Variable(typeof(object));
|
||||||
var exps = new List<Expression>(new Expression[] {
|
var exps = new List<Expression>(new Expression[] {
|
||||||
Expression.Assign(var1Parm, Expression.TypeAs(parm1, table.Type)),
|
Expression.Assign(var1Parm, Expression.TypeAs(parm1, table.Type)),
|
||||||
Expression.Assign(
|
Expression.Assign(
|
||||||
var2Ret,
|
var2Ret,
|
||||||
Expression.Convert(Expression.MakeMemberAccess(var1Parm, table.Properties[pn]), typeof(object))
|
Expression.Convert(Expression.MakeMemberAccess(var1Parm, table.Properties[pn]), typeof(object))
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
exps.AddRange(new Expression[] {
|
exps.AddRange(new Expression[] {
|
||||||
Expression.Return(returnTarget, var2Ret),
|
Expression.Return(returnTarget, var2Ret),
|
||||||
Expression.Label(returnTarget, Expression.Default(typeof(object)))
|
Expression.Label(returnTarget, Expression.Default(typeof(object)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user