mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
- 修改 IncludeMany ManyToMany ET 缓存的 bug;
- 完善 IncludeMany 联合键处理; - 完善 Include/IncludeMany 单元测试; - 修复 Include 延时加载 ManyToOne/OneToOne,当值为 null 时,仍然会查询一次数据;
This commit is contained in:
parent
c450176aec
commit
dbfc33fef5
@ -763,7 +763,69 @@ namespace FreeSql.Tests.Sqlite {
|
|||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Include_OneToChilds() {
|
public void Include_OneToChilds() {
|
||||||
|
var tag1 = new Tag {
|
||||||
|
Ddd = DateTime.Now.Second,
|
||||||
|
Name = "test_oneToChilds_01_中国"
|
||||||
|
};
|
||||||
|
tag1.Id = (int)g.sqlite.Insert(tag1).ExecuteIdentity();
|
||||||
|
var tag1_1 = new Tag {
|
||||||
|
Parent_id = tag1.Id,
|
||||||
|
Ddd = DateTime.Now.Second,
|
||||||
|
Name = "test_oneToChilds_01_北京"
|
||||||
|
};
|
||||||
|
tag1_1.Id = (int)g.sqlite.Insert(tag1_1).ExecuteIdentity();
|
||||||
|
var tag1_2 = new Tag {
|
||||||
|
Parent_id = tag1.Id,
|
||||||
|
Ddd = DateTime.Now.Second,
|
||||||
|
Name = "test_oneToChilds_01_上海"
|
||||||
|
};
|
||||||
|
tag1_2.Id = (int)g.sqlite.Insert(tag1_2).ExecuteIdentity();
|
||||||
|
|
||||||
|
var tag2 = new Tag {
|
||||||
|
Ddd = DateTime.Now.Second,
|
||||||
|
Name = "test_oneToChilds_02_美国"
|
||||||
|
};
|
||||||
|
tag2.Id = (int)g.sqlite.Insert(tag2).ExecuteIdentity();
|
||||||
|
var tag2_1 = new Tag {
|
||||||
|
Parent_id = tag2.Id,
|
||||||
|
Ddd = DateTime.Now.Second,
|
||||||
|
Name = "test_oneToChilds_02_纽约"
|
||||||
|
};
|
||||||
|
tag2_1.Id = (int)g.sqlite.Insert(tag2_1).ExecuteIdentity();
|
||||||
|
var tag2_2 = new Tag {
|
||||||
|
Parent_id = tag2.Id,
|
||||||
|
Ddd = DateTime.Now.Second,
|
||||||
|
Name = "test_oneToChilds_02_华盛顿"
|
||||||
|
};
|
||||||
|
tag2_2.Id = (int)g.sqlite.Insert(tag2_2).ExecuteIdentity();
|
||||||
|
|
||||||
|
var tags0 = g.sqlite.Select<Tag>()
|
||||||
|
.Include(a => a.Parent)
|
||||||
|
.Where(a => a.Id == tag1.Id || a.Id == tag2.Id)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var tags = g.sqlite.Select<Tag>()
|
||||||
|
.IncludeMany(a => a.Tags)
|
||||||
|
.Include(a => a.Parent)
|
||||||
|
.IncludeMany(a => a.Songs)
|
||||||
|
.Where(a => a.Id == tag1.Id || a.Id == tag2.Id)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var tags2 = g.sqlite.Select<Tag>()
|
||||||
|
.IncludeMany(a => a.Tags,
|
||||||
|
then => then.Include(a => a.Parent).IncludeMany(a => a.Songs))
|
||||||
|
.Include(a => a.Parent)
|
||||||
|
.IncludeMany(a => a.Songs)
|
||||||
|
.Where(a => a.Id == tag1.Id || a.Id == tag2.Id)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var tags3 = g.sqlite.Select<Tag>()
|
||||||
|
.IncludeMany(a => a.Tags,
|
||||||
|
then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags))
|
||||||
|
.Include(a => a.Parent)
|
||||||
|
.IncludeMany(a => a.Songs)
|
||||||
|
.Where(a => a.Id == tag1.Id || a.Id == tag2.Id)
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -813,7 +875,22 @@ namespace FreeSql.Tests.Sqlite {
|
|||||||
|
|
||||||
var songs = g.sqlite.Select<Song>()
|
var songs = g.sqlite.Select<Song>()
|
||||||
.IncludeMany(a => a.Tags)
|
.IncludeMany(a => a.Tags)
|
||||||
|
.Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
Assert.Equal(3, songs.Count);
|
||||||
|
Assert.Equal(2, songs[0].Tags.Count);
|
||||||
|
Assert.Equal(1, songs[1].Tags.Count);
|
||||||
|
Assert.Equal(3, songs[2].Tags.Count);
|
||||||
|
|
||||||
|
var songs2 = g.sqlite.Select<Song>()
|
||||||
|
.IncludeMany(a => a.Tags,
|
||||||
|
then => then.IncludeMany(t => t.Songs))
|
||||||
|
.Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id)
|
||||||
|
.ToList();
|
||||||
|
Assert.Equal(3, songs2.Count);
|
||||||
|
Assert.Equal(2, songs2[0].Tags.Count);
|
||||||
|
Assert.Equal(1, songs2[1].Tags.Count);
|
||||||
|
Assert.Equal(3, songs2[2].Tags.Count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<Version>0.5.13</Version>
|
<Version>0.5.14</Version>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Authors>YeXiangQin</Authors>
|
<Authors>YeXiangQin</Authors>
|
||||||
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
|
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
|
||||||
|
@ -286,8 +286,6 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||||
}
|
}
|
||||||
_orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret));
|
|
||||||
_trackToList?.Invoke(ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -315,13 +313,18 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||||
_orm.Aop.CurdAfter?.Invoke(this, after);
|
_orm.Aop.CurdAfter?.Invoke(this, after);
|
||||||
}
|
}
|
||||||
_orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret));
|
|
||||||
_trackToList?.Invoke(ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
internal List<T1> ToListPrivate(GetAllFieldExpressionTreeInfo af, (ReadAnonymousTypeInfo, List<object>)[] otherData) {
|
internal List<T1> ToListPrivate(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List<object> retlist)[] otherData) {
|
||||||
var sql = this.ToSql(af.Field);
|
string sql = null;
|
||||||
|
if (otherData?.Length > 0) {
|
||||||
|
var sbField = new StringBuilder().Append(af.Field);
|
||||||
|
foreach (var other in otherData)
|
||||||
|
sbField.Append(other.field);
|
||||||
|
sql = this.ToSql(sbField.ToString());
|
||||||
|
} else
|
||||||
|
sql = this.ToSql(af.Field);
|
||||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
|
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
|
||||||
|
|
||||||
return _orm.Cache.Shell(_cache.key, _cache.seconds, () => {
|
return _orm.Cache.Shell(_cache.key, _cache.seconds, () => {
|
||||||
@ -336,7 +339,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (otherData != null) {
|
if (otherData != null) {
|
||||||
var idx = af.FieldCount - 1;
|
var idx = af.FieldCount - 1;
|
||||||
foreach (var other in otherData)
|
foreach (var other in otherData)
|
||||||
other.Item2.Add(_commonExpression.ReadAnonymous(other.Item1, dr, ref idx, false));
|
other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false));
|
||||||
}
|
}
|
||||||
}, CommandType.Text, sql, dbParms);
|
}, CommandType.Text, sql, dbParms);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
@ -352,8 +355,15 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async internal Task<List<T1>> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, (ReadAnonymousTypeInfo, List<object>)[] otherData) {
|
async internal Task<List<T1>> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List<object> retlist)[] otherData) {
|
||||||
var sql = this.ToSql(af.Field);
|
string sql = null;
|
||||||
|
if (otherData?.Length > 0) {
|
||||||
|
var sbField = new StringBuilder().Append(af.Field);
|
||||||
|
foreach (var other in otherData)
|
||||||
|
sbField.Append(other.field);
|
||||||
|
sql = this.ToSql(sbField.ToString());
|
||||||
|
} else
|
||||||
|
sql = this.ToSql(af.Field);
|
||||||
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
|
if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
|
||||||
|
|
||||||
return await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => {
|
return await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => {
|
||||||
@ -368,7 +378,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (otherData != null) {
|
if (otherData != null) {
|
||||||
var idx = af.FieldCount - 1;
|
var idx = af.FieldCount - 1;
|
||||||
foreach (var other in otherData)
|
foreach (var other in otherData)
|
||||||
other.Item2.Add(_commonExpression.ReadAnonymous(other.Item1, dr, ref idx, false));
|
other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false));
|
||||||
}
|
}
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}, CommandType.Text, sql, dbParms);
|
}, CommandType.Text, sql, dbParms);
|
||||||
@ -501,13 +511,30 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
var tb = _tables.First();
|
var tb = _tables.First();
|
||||||
var index = 0;
|
var index = 0;
|
||||||
|
|
||||||
|
var tborder = new[] { tb }.Concat(_tables.ToArray().Where((a, b) => b > 0).OrderBy(a => a.Alias));
|
||||||
var tbiindex = 0;
|
var tbiindex = 0;
|
||||||
foreach (var tbi in _tables.ToArray().OrderBy(a => a.Alias)) {
|
foreach (var tbi in tborder) {
|
||||||
if (tbiindex > 0 && tbi.Type == SelectTableInfoType.From) continue;
|
if (tbiindex > 0 && tbi.Type == SelectTableInfoType.From) continue;
|
||||||
if (tbiindex > 0 && tbi.Alias.StartsWith($"{tb.Alias}__") == false) continue;
|
if (tbiindex > 0 && tbi.Alias.StartsWith($"{tb.Alias}__") == false) continue;
|
||||||
|
|
||||||
var typei = tbi.Table.TypeLazy ?? tbi.Table.Type;
|
var typei = tbi.Table.TypeLazy ?? tbi.Table.Type;
|
||||||
Expression curExp = retExp;
|
Expression curExp = retExp;
|
||||||
|
|
||||||
|
var colidx = 0;
|
||||||
|
foreach (var col in tbi.Table.Columns.Values) {
|
||||||
|
if (index > 0) {
|
||||||
|
field.Append(", ");
|
||||||
|
if (tbiindex > 0 && colidx == 0) field.Append("\r\n");
|
||||||
|
}
|
||||||
|
var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name);
|
||||||
|
field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tbi.Alias}.{quoteName}"));
|
||||||
|
++index;
|
||||||
|
if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index);
|
||||||
|
else dicfield.Add(quoteName, true);
|
||||||
|
++colidx;
|
||||||
|
}
|
||||||
|
tbiindex++;
|
||||||
|
|
||||||
if (tbiindex == 0)
|
if (tbiindex == 0)
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })),
|
Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })),
|
||||||
@ -547,7 +574,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (iscontinue) continue;
|
if (iscontinue) continue;
|
||||||
|
|
||||||
blockExp.Add(
|
blockExp.Add(
|
||||||
Expression.IfThen(
|
Expression.IfThenElse(
|
||||||
curExpIfNotNull,
|
curExpIfNotNull,
|
||||||
Expression.Block(new Expression[] {
|
Expression.Block(new Expression[] {
|
||||||
Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })),
|
Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })),
|
||||||
@ -555,11 +582,16 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
||||||
Expression.Assign(dataIndexExp, readExpDataIndex)
|
Expression.Assign(dataIndexExp, readExpDataIndex)
|
||||||
),
|
),
|
||||||
Expression.IfThen(
|
Expression.IfThenElse(
|
||||||
Expression.NotEqual(readExpValue, Expression.Constant(null)),
|
Expression.NotEqual(readExpValue, Expression.Constant(null)),
|
||||||
Expression.Assign(curExp, Expression.Convert(readExpValue, typei))
|
Expression.Assign(curExp, Expression.Convert(readExpValue, typei)),
|
||||||
|
Expression.Assign(curExp, Expression.Constant(null, typei))
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
Expression.Block(
|
||||||
|
Expression.Assign(readExpValue, Expression.Constant(null, typeof(object))),
|
||||||
|
Expression.Assign(dataIndexExp, Expression.Constant(index))
|
||||||
)
|
)
|
||||||
})
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -571,21 +603,6 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
Expression.Call(Expression.TypeAs(readExpValue, typei), tbi.Table.TypeLazySetOrm, ormExp)
|
Expression.Call(Expression.TypeAs(readExpValue, typei), tbi.Table.TypeLazySetOrm, ormExp)
|
||||||
)
|
)
|
||||||
); //将 orm 传递给 lazy
|
); //将 orm 传递给 lazy
|
||||||
|
|
||||||
var colidx = 0;
|
|
||||||
foreach (var col in tbi.Table.Columns.Values) {
|
|
||||||
if (index > 0) {
|
|
||||||
field.Append(", ");
|
|
||||||
if (tbiindex > 0 && colidx == 0) field.Append("\r\n");
|
|
||||||
}
|
|
||||||
var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name);
|
|
||||||
field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tbi.Alias}.{quoteName}"));
|
|
||||||
++index;
|
|
||||||
if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index);
|
|
||||||
else dicfield.Add(quoteName, true);
|
|
||||||
++colidx;
|
|
||||||
}
|
|
||||||
tbiindex++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
@ -685,9 +702,17 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
||||||
Expression.Assign(dataIndexExp, readExpDataIndex)),
|
Expression.Assign(dataIndexExp, readExpDataIndex)),
|
||||||
//Expression.Call(typeof(Trace).GetMethod("WriteLine", new Type[]{typeof(string)}), Expression.Call(typeof(string).GetMethod("Concat", new Type[]{typeof(object) }), readExpValue)),
|
//Expression.Call(typeof(Trace).GetMethod("WriteLine", new Type[]{typeof(string)}), Expression.Call(typeof(string).GetMethod("Concat", new Type[]{typeof(object) }), readExpValue)),
|
||||||
Expression.IfThen(Expression.NotEqual(readExpValue, Expression.Constant(null)),
|
|
||||||
//Expression.Call(retExp, propGetSetMethod, Expression.Default(prop.PropertyType)),
|
tb1.TypeLazy != null ?
|
||||||
Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)))
|
Expression.IfThenElse(
|
||||||
|
Expression.NotEqual(readExpValue, Expression.Constant(null)),
|
||||||
|
Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)),
|
||||||
|
Expression.Call(retExp, propGetSetMethod, Expression.Convert(Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Constant(null)), prop.PropertyType))
|
||||||
|
) :
|
||||||
|
Expression.IfThen(
|
||||||
|
Expression.NotEqual(readExpValue, Expression.Constant(null)),
|
||||||
|
Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType))
|
||||||
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (otherindex == 0) { //不读导航属性,优化单表读取性能
|
if (otherindex == 0) { //不读导航属性,优化单表读取性能
|
||||||
|
@ -343,13 +343,15 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
|
|
||||||
if (collMem.Expression.NodeType != ExpressionType.Parameter)
|
if (collMem.Expression.NodeType != ExpressionType.Parameter)
|
||||||
_commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null);
|
_commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null);
|
||||||
var tbref = tb.GetTableRef(collMem.Member.Name, true);
|
|
||||||
|
|
||||||
_includeToList.Enqueue(listObj => {
|
_includeToList.Enqueue(listObj => {
|
||||||
var list = listObj as List<T1>;
|
var list = listObj as List<T1>;
|
||||||
if (list == null) return;
|
if (list == null) return;
|
||||||
if (list.Any() == false) return;
|
if (list.Any() == false) return;
|
||||||
|
|
||||||
|
var tbref = tb.GetTableRef(collMem.Member.Name, true);
|
||||||
|
if (tbref.Columns.Any() == false) return;
|
||||||
|
|
||||||
var t1parm = Expression.Parameter(typeof(T1));
|
var t1parm = Expression.Parameter(typeof(T1));
|
||||||
Expression membersExp = t1parm;
|
Expression membersExp = t1parm;
|
||||||
while (members.Any()) membersExp = Expression.MakeMemberAccess(membersExp, members.Pop());
|
while (members.Any()) membersExp = Expression.MakeMemberAccess(membersExp, members.Pop());
|
||||||
@ -381,7 +383,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (true) {
|
if (true) {
|
||||||
var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType);
|
var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType);
|
||||||
if (tbref.Columns.Count == 1) {
|
if (tbref.Columns.Count == 1) {
|
||||||
var arrExp = Expression.NewArrayInit(tbref.Columns[0].CsType, list.Select(a => Expression.Constant(Convert.ChangeType(getListValue(a, tbref.Columns[0].CsName), tbref.Columns[0].CsType))).ToArray());
|
var arrExp = Expression.NewArrayInit(tbref.Columns[0].CsType, list.Select(a => Expression.Constant(Convert.ChangeType(getListValue(a, tbref.Columns[0].CsName), tbref.Columns[0].CsType))).Distinct().ToArray());
|
||||||
var otmExpParm1 = Expression.Parameter(typeof(TNavigate), "a");
|
var otmExpParm1 = Expression.Parameter(typeof(TNavigate), "a");
|
||||||
var containsMethod = _dicTypeMethod.GetOrAdd(tbref.Columns[0].CsType, et => new ConcurrentDictionary<string, MethodInfo>()).GetOrAdd("Contains", mn =>
|
var containsMethod = _dicTypeMethod.GetOrAdd(tbref.Columns[0].CsType, et => new ConcurrentDictionary<string, MethodInfo>()).GetOrAdd("Contains", mn =>
|
||||||
typeof(Enumerable).GetMethods().Where(a => a.Name == mn).First()).MakeGenericMethod(tbref.Columns[0].CsType);
|
typeof(Enumerable).GetMethods().Where(a => a.Name == mn).First()).MakeGenericMethod(tbref.Columns[0].CsType);
|
||||||
@ -466,21 +468,34 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (true) {
|
if (true) {
|
||||||
var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType);
|
var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType);
|
||||||
var tbrefMid = _commonUtils.GetTableByEntity(tbref.RefMiddleEntityType);
|
var tbrefMid = _commonUtils.GetTableByEntity(tbref.RefMiddleEntityType);
|
||||||
|
var sbJoin = new StringBuilder().Append($"{_commonUtils.QuoteSqlName(tbrefMid.DbName)} midtb ON");
|
||||||
|
for (var z = 0; z < tbref.RefColumns.Count; z++) {
|
||||||
|
if (z > 0) sbJoin.Append(" AND");
|
||||||
|
sbJoin.Append($" midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[tbref.Columns.Count + z].Attribute.Name)} = a.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}");
|
||||||
|
}
|
||||||
|
subSelect.InnerJoin(sbJoin.ToString());
|
||||||
|
sbJoin.Clear();
|
||||||
if (tbref.Columns.Count == 1) {
|
if (tbref.Columns.Count == 1) {
|
||||||
//var midParmExp = Expression.Parameter(tbref.RefMiddleEntityType, "midtb");
|
subSelect.Where(_commonUtils.FormatSql($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[0].Attribute.Name)} in {{0}}", list.Select(a => getListValue(a, tbref.Columns[0].CsName)).Distinct()));
|
||||||
//(subSelect as Select1Provider<TNavigate>)._tables.Add(new SelectTableInfo {
|
|
||||||
// Alias = "midtb",
|
|
||||||
// AliasInit = "midtb",
|
|
||||||
// On = $"{_commonUtils.QuoteSqlName(tbrefMid.DbName)} midtb ON midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[1].Attribute.Name)} = a.{_commonUtils.QuoteSqlName(tbref.RefColumns[0].Attribute.Name)}",
|
|
||||||
// Parameter = midParmExp,
|
|
||||||
// Table = tbrefMid,
|
|
||||||
// Type = SelectTableInfoType.InnerJoin
|
|
||||||
//});
|
|
||||||
subSelect.InnerJoin($"{_commonUtils.QuoteSqlName(tbrefMid.DbName)} midtb ON midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[1].Attribute.Name)} = a.{_commonUtils.QuoteSqlName(tbref.RefColumns[0].Attribute.Name)}");
|
|
||||||
subSelect.Where(_commonUtils.FormatSql($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[0].Attribute.Name)} in {{0}}", list.Select(a => getListValue(a, tbref.Columns[0].CsName))));
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
Dictionary<string, bool> sbDic = new Dictionary<string, bool>();
|
||||||
|
for (var y = 0; y < list.Count; y++) {
|
||||||
|
var sbWhereOne = new StringBuilder();
|
||||||
|
sbWhereOne.Append(" (");
|
||||||
|
for (var z = 0; z < tbref.Columns.Count; z++) {
|
||||||
|
if (z > 0) sbWhereOne.Append(" AND");
|
||||||
|
sbWhereOne.Append(_commonUtils.FormatSql($" midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[z].Attribute.Name)}={{0}}", getListValue(list[y], tbref.Columns[z].CsName)));
|
||||||
|
}
|
||||||
|
sbWhereOne.Append(")");
|
||||||
|
var whereOne = sbWhereOne.ToString();
|
||||||
|
sbWhereOne.Clear();
|
||||||
|
if (sbDic.ContainsKey(whereOne) == false) sbDic.Add(whereOne, true);
|
||||||
|
}
|
||||||
|
var sbWhere = new StringBuilder();
|
||||||
|
foreach (var sbd in sbDic)
|
||||||
|
sbWhere.Append(" OR").Append(sbd.Key);
|
||||||
|
subSelect.Where(sbWhere.Remove(0, 3).ToString());
|
||||||
|
sbWhere.Clear();
|
||||||
}
|
}
|
||||||
then?.Invoke(subSelect);
|
then?.Invoke(subSelect);
|
||||||
|
|
||||||
@ -490,7 +505,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
var subSelectP1 = (subSelect as Select1Provider<TNavigate>);
|
var subSelectP1 = (subSelect as Select1Provider<TNavigate>);
|
||||||
var af = subSelectP1.GetAllFieldExpressionTreeLevelAll();
|
var af = subSelectP1.GetAllFieldExpressionTreeLevelAll();
|
||||||
if (_selectExpression == null) {// return this.InternalToList<T1>(_selectExpression).Select(a => (a, ()).ToList();
|
if (_selectExpression == null) {// return this.InternalToList<T1>(_selectExpression).Select(a => (a, ()).ToList();
|
||||||
var sb = new StringBuilder().Append(af.Field);
|
var field = new StringBuilder();
|
||||||
var read = new ReadAnonymousTypeInfo();
|
var read = new ReadAnonymousTypeInfo();
|
||||||
read.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
|
read.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
|
||||||
read.Consturctor = tbrefMid.TypeLazy.GetConstructor(new Type[0]);
|
read.Consturctor = tbrefMid.TypeLazy.GetConstructor(new Type[0]);
|
||||||
@ -505,10 +520,9 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
Property = tbrefMid.Properties[col.CsName]
|
Property = tbrefMid.Properties[col.CsName]
|
||||||
};
|
};
|
||||||
read.Childs.Add(child);
|
read.Childs.Add(child);
|
||||||
sb.Append(", ").Append(_commonUtils.QuoteReadColumn(child.MapType, child.DbField));
|
field.Append(", ").Append(_commonUtils.QuoteReadColumn(child.MapType, child.DbField));
|
||||||
}
|
}
|
||||||
af.Field = sb.ToString();
|
subList = subSelectP1.ToListPrivate(af, new[] { (field.ToString(), read, midList) });
|
||||||
subList = subSelectP1.ToListPrivate(af, new[] { (read, midList) });
|
|
||||||
} else
|
} else
|
||||||
subList = subSelectP1.ToListPrivate(af, null);
|
subList = subSelectP1.ToListPrivate(af, null);
|
||||||
|
|
||||||
@ -518,17 +532,25 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<string, Tuple<T1, List<TNavigate>>> dicList = new Dictionary<string, Tuple<T1, List<TNavigate>>>();
|
Dictionary<string, List<Tuple<T1, List<TNavigate>>>> dicList = new Dictionary<string, List<Tuple<T1, List<TNavigate>>>>();
|
||||||
foreach (var item in list) {
|
foreach (var item in list) {
|
||||||
if (tbref.Columns.Count == 1) {
|
if (tbref.Columns.Count == 1) {
|
||||||
dicList.Add(getListValue(item, tbref.Columns[0].CsName).ToString(), Tuple.Create(item, new List<TNavigate>()));
|
var dicListKey = getListValue(item, tbref.Columns[0].CsName).ToString();
|
||||||
|
var dicListVal = Tuple.Create(item, new List<TNavigate>());
|
||||||
|
if (dicList.TryGetValue(dicListKey, out var items) == false)
|
||||||
|
dicList.Add(dicListKey, items = new List<Tuple<T1, List<TNavigate>>>());
|
||||||
|
items.Add(dicListVal);
|
||||||
} else {
|
} else {
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
for (var z = 0; z < tbref.Columns.Count; z++) {
|
for (var z = 0; z < tbref.Columns.Count; z++) {
|
||||||
if (z > 0) sb.Append("*$*");
|
if (z > 0) sb.Append("*$*");
|
||||||
sb.Append(getListValue(item, tbref.Columns[z].CsName));
|
sb.Append(getListValue(item, tbref.Columns[z].CsName));
|
||||||
}
|
}
|
||||||
dicList.Add(sb.Remove(0, 3).ToString(), Tuple.Create(item, new List<TNavigate>()));
|
var dicListKey = sb.Remove(0, 3).ToString();
|
||||||
|
var dicListVal = Tuple.Create(item, new List<TNavigate>());
|
||||||
|
if (dicList.TryGetValue(dicListKey, out var items) == false)
|
||||||
|
dicList.Add(dicListKey, items = new List<Tuple<T1, List<TNavigate>>>());
|
||||||
|
items.Add(dicListVal);
|
||||||
sb.Clear();
|
sb.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -545,10 +567,12 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
key = sb.ToString();
|
key = sb.ToString();
|
||||||
sb.Clear();
|
sb.Clear();
|
||||||
}
|
}
|
||||||
if (dicList.TryGetValue(key, out var t1item) == false) return;
|
if (dicList.TryGetValue(key, out var t1items) == false) return;
|
||||||
|
foreach (var t1item in t1items)
|
||||||
t1item.Item2.Add(subList[a]);
|
t1item.Item2.Add(subList[a]);
|
||||||
}
|
}
|
||||||
foreach (var t1item in dicList.Values)
|
foreach (var t1items in dicList.Values)
|
||||||
|
foreach (var t1item in t1items)
|
||||||
setListValue(t1item.Item1, t1item.Item2);
|
setListValue(t1item.Item1, t1item.Item2);
|
||||||
dicList.Clear();
|
dicList.Clear();
|
||||||
}
|
}
|
||||||
|
@ -605,7 +605,10 @@ namespace FreeSql.Internal {
|
|||||||
.Append(" }\r\n");
|
.Append(" }\r\n");
|
||||||
}
|
}
|
||||||
if (vp.Item3) { //set 重写
|
if (vp.Item3) { //set 重写
|
||||||
cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;");
|
cscode.Append(" set {\r\n")
|
||||||
|
.Append(" base.").Append(pnv.Name).AppendLine(" = value;")
|
||||||
|
.Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;")
|
||||||
|
.Append(" }\r\n");
|
||||||
}
|
}
|
||||||
cscode.AppendLine(" }");
|
cscode.AppendLine(" }");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user