mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 18:52:50 +08:00
add ArrayToMany IncludeMany
This commit is contained in:
parent
8ca0414500
commit
5e5d464224
@ -670,10 +670,11 @@ namespace FreeSql.Internal.CommonProvider
|
||||
}
|
||||
//members.Clear(); 此行影响 ToChunk 第二次
|
||||
|
||||
var isObservableCollection = collMem.Type == typeof(ObservableCollection<TNavigate>);
|
||||
var listValueExp = Expression.Parameter(typeof(List<TNavigate>), "listValue");
|
||||
var setListValue = membersExpNotNull == null ?
|
||||
Expression.Lambda<Action<T1, List<TNavigate>>>(
|
||||
collMem.Type == typeof(ObservableCollection<TNavigate>) ?
|
||||
isObservableCollection ?
|
||||
(Expression)Expression.IfThen(
|
||||
Expression.NotEqual(listValueExp, Expression.Constant(null, typeof(List<TNavigate>))),
|
||||
Expression.Assign(Expression.MakeMemberAccess(membersExp, collMem.Member), Expression.New(typeof(ObservableCollection<TNavigate>).GetConstructor(new[] { typeof(List<TNavigate>) }), listValueExp))
|
||||
@ -681,7 +682,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
Expression.Assign(Expression.MakeMemberAccess(membersExp, collMem.Member), Expression.TypeAs(listValueExp, collMem.Type))
|
||||
, t1parm, listValueExp).Compile() :
|
||||
Expression.Lambda<Action<T1, List<TNavigate>>>(Expression.IfThen(membersExpNotNull,
|
||||
collMem.Type == typeof(ObservableCollection<TNavigate>) ?
|
||||
isObservableCollection ?
|
||||
(Expression)Expression.IfThen(
|
||||
Expression.NotEqual(listValueExp, Expression.Constant(null, typeof(List<TNavigate>))),
|
||||
Expression.Assign(Expression.MakeMemberAccess(membersExp, collMem.Member), Expression.New(typeof(ObservableCollection<TNavigate>).GetConstructor(new[] { typeof(List<TNavigate>) }), listValueExp))
|
||||
@ -1175,6 +1176,124 @@ namespace FreeSql.Internal.CommonProvider
|
||||
}
|
||||
break;
|
||||
case TableRefType.ArrayToMany:
|
||||
if (true)
|
||||
{
|
||||
var subList = new List<TNavigate>();
|
||||
var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType);
|
||||
if (tbref.RefColumns[0] == tbref2.Primarys[0])
|
||||
{
|
||||
var listKeys = list.Select(a =>
|
||||
{
|
||||
var arrVal = getListValue(a, tbref.Columns[0].CsName, 0) as Array;
|
||||
var arrObjVal = new object[arrVal.Length];
|
||||
arrVal.CopyTo(arrObjVal, 0);
|
||||
return arrObjVal;
|
||||
}).Where(a => a != null).ToArray();
|
||||
var arrExp = Expression.NewArrayInit(tbref.RefColumns[0].CsType, listKeys.SelectMany(a => a).Distinct()
|
||||
.Select(a => Expression.Constant(Utils.GetDataReaderValue(tbref.RefColumns[0].CsType, a), tbref.RefColumns[0].CsType)).ToArray());
|
||||
var otmExpParm1 = Expression.Parameter(typeof(TNavigate), "a");
|
||||
var containsMethod = _dicTypeMethod.GetOrAdd(tbref.RefColumns[0].CsType, et => new ConcurrentDictionary<string, MethodInfo>()).GetOrAdd("Contains", mn =>
|
||||
typeof(Enumerable).GetMethods().Where(a => a.Name == mn).First()).MakeGenericMethod(tbref.RefColumns[0].CsType);
|
||||
var refCol = Expression.MakeMemberAccess(otmExpParm1, tbref2.Properties[tbref.RefColumns[0].CsName]);
|
||||
subSelect.Where(Expression.Lambda<Func<TNavigate, bool>>(
|
||||
Expression.Call(null, containsMethod, arrExp, refCol), otmExpParm1));
|
||||
|
||||
if (isAsync)
|
||||
{
|
||||
#if net40
|
||||
#else
|
||||
if (selectExp == null) subList = await subSelect.ToListAsync(true, cancellationToken);
|
||||
else subList = await subSelect.ToListAsync<TNavigate>(selectExp, cancellationToken);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selectExp == null) subList = subSelect.ToList(true);
|
||||
else subList = subSelect.ToList<TNavigate>(selectExp);
|
||||
}
|
||||
|
||||
if (subList.Any() == false)
|
||||
{
|
||||
foreach (var item in list)
|
||||
setListValue(item, new List<TNavigate>());
|
||||
return;
|
||||
}
|
||||
var dicSubList = subList.ToDictionary(a => EntityUtilExtensions.GetEntityValueWithPropertyName(_orm, tbref.RefEntityType, a, tbref.RefColumns[0].CsName)?.ToString(), a => a);
|
||||
|
||||
var parentNavs = new List<string>();
|
||||
foreach (var navProp in tbref2.Properties)
|
||||
{
|
||||
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;
|
||||
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);
|
||||
}
|
||||
for (var y = 0; y < list.Count; y++)
|
||||
{
|
||||
var item = list[y];
|
||||
var dicListKeys = listKeys[y];
|
||||
var navs = new List<TNavigate>();
|
||||
foreach (var dlk in dicListKeys)
|
||||
{
|
||||
if (dlk == null)
|
||||
{
|
||||
navs.Add(null);
|
||||
continue;
|
||||
}
|
||||
var dicListKey = dlk.ToString();
|
||||
dicSubList.TryGetValue(dicListKey, out var nav);
|
||||
navs.Add(nav);
|
||||
}
|
||||
setListValue(item, navs);
|
||||
}
|
||||
dicSubList.Clear();
|
||||
subList.Clear();
|
||||
}
|
||||
else if (tbref.Columns[0] == tb.Primarys[0])
|
||||
{
|
||||
var listKeys = list.Select(a => getListValue(a, tbref.Columns[0].CsName, 0)).Distinct()
|
||||
.Select(a => Utils.GetDataReaderValue(tbref.RefColumns[0].CsType.GetElementType(), a)).ToArray();
|
||||
var listKeysSql = _commonUtils.GetNoneParamaterSqlValue(subSelect._params, "arrtm", tbref.RefColumns[0], tbref.RefColumns[0].CsType, listKeys);
|
||||
subSelect.Where($"{subSelectT1Alias}.{_commonUtils.QuoteSqlName(tbref.RefColumns[0].Attribute.Name)} && {listKeysSql}");
|
||||
|
||||
if (isAsync)
|
||||
{
|
||||
#if net40
|
||||
#else
|
||||
if (selectExp == null) subList = await subSelect.ToListAsync(true, cancellationToken);
|
||||
else subList = await subSelect.ToListAsync<TNavigate>(selectExp, cancellationToken);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selectExp == null) subList = subSelect.ToList(true);
|
||||
else subList = subSelect.ToList<TNavigate>(selectExp);
|
||||
}
|
||||
|
||||
if (subList.Any() == false)
|
||||
{
|
||||
foreach (var item in list)
|
||||
setListValue(item, new List<TNavigate>());
|
||||
return;
|
||||
}
|
||||
var subListDic = subList.Select(a => {
|
||||
var arrVal = EntityUtilExtensions.GetEntityValueWithPropertyName(_orm, tbref2.Type, a, tbref.RefColumns[0].CsName) as Array;
|
||||
var arrObjVal = new object[arrVal.Length];
|
||||
arrVal.CopyTo(arrObjVal, 0);
|
||||
return arrObjVal.Select(b => NativeTuple.Create(a, b?.ToString()));
|
||||
}).SelectMany(a => a).GroupBy(a => a.Item2).ToDictionary(a => a.Key, a => a.Select(b => b.Item1).ToList());
|
||||
foreach (var item in list)
|
||||
{
|
||||
var itemKey = getListValue(item, tbref.Columns[0].CsName, 0)?.ToString();
|
||||
subListDic.TryGetValue(itemKey, out var navs);
|
||||
setListValue(item, navs);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user