Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into i18n-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
luoyunchong committed May 22, 2022
2 parents a2ad37a + 3782b02 commit fbbc043
Show file tree
Hide file tree
Showing 10 changed files with 309 additions and 65 deletions.
33 changes: 21 additions & 12 deletions Examples/base_entity/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ static void Main(string[] args)

//.UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789")

.UseMonitorCommand(null, (umcmd, log) => Console.WriteLine(umcmd.Connection.ConnectionString + ":" + umcmd.CommandText))
.UseMonitorCommand(null, (umcmd, log) => Console.WriteLine(umcmd.Connection.ConnectionString + ":" + umcmd.CommandText + "\r\n"))
.UseLazyLoading(true)
.UseGenerateCommandParameterWithLambda(true)
.Build();
Expand Down Expand Up @@ -289,17 +289,26 @@ static void Main(string[] args)
});
sql1 = sql1.Replace("INNER JOIN ", "FULL JOIN ");

//fsql.Select<UserGroup>()
// .ToList(a => new
// {
// users1 = fsql.Select<User1>().Where(b => b.GroupId == a.Id).ToList(false),
// users2 = fsql.Select<User1>().Where(b => b.GroupId == a.Id).ToList(b => new
// {
// userid = b.Id,
// username = b.Username
// }),
// //users3 = fsql.Ado.Query<User1>("select * from user1 where groupid = @id", new { id = a.Id })
// });
var tinc01 = fsql.Select<UserGroup>().IncludeMany(a => a.User1s.Where(b => b.GroupId == a.Id)).ToList();
var tsub01 = fsql.Select<UserGroup>()
.ToList(a => new
{
users1 = fsql.Select<User1>().Where(b => b.GroupId == a.Id).ToList(),
users2 = fsql.Select<User1>().Where(b => b.GroupId == a.Id).ToList(b => new
{
userid = b.Id,
username = b.Username
}),
users3 = fsql.Select<User1>().Limit(10).ToList(),
users4 = fsql.Select<User1>().Limit(10).ToList(b => new
{
userid = b.Id,
username = b.Username
})
//users3 = fsql.Ado.Query<User1>("select * from user1 where groupid = @id", new { id = a.Id })
});





Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public SelectedQueryProvider(Select0Provider select, Expression selector)
var index = -10000; //临时规则,不返回 as1

if (selector != null)
_comonExp.ReadAnonymousField(_select._tables, field, _map, ref index, selector, null, null, _select._whereGlobalFilter, null, false); //不走 DTO 映射,不处理 IncludeMany
_comonExp.ReadAnonymousField(_select._tables, field, _map, ref index, selector, null, null, _select._whereGlobalFilter, null, null, false); //不走 DTO 映射,不处理 IncludeMany
_field = field.ToString();
}

Expand Down
8 changes: 7 additions & 1 deletion FreeSql/FreeSql.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion FreeSql/Interface/Curd/ISelect/ISelect0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,14 @@ public partial interface ISelect0<TSelect, T1> : ISelect0
/// 3、ToList((a, b, c) => new { a, b, c }) 这样也可以<para></para>
/// 4、abc 怎么来的?请试试 fsql.Select&lt;T1, T2, T3&gt;()
/// </summary>
/// <returns></returns>
List<T1> ToList(); //因为 LambdaExpression 不支持默认参数方法,所以与 ToList(includeNestedMembers) 单独定义
/// <summary>
/// 执行SQL查询,返回 T1 实体、以及 LeftJoin/InnerJoin/RightJoin 对象
/// </summary>
/// <param name="includeNestedMembers">false: 返回 2级 LeftJoin/InnerJoin/RightJoin 对象;true: 返回所有 LeftJoin/InnerJoin/RightJoin 的导航数据</param>
/// <returns></returns>
List<T1> ToList(bool includeNestedMembers = false);
List<T1> ToList(bool includeNestedMembers);
/// <summary>
/// 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。
/// </summary>
Expand Down
48 changes: 31 additions & 17 deletions FreeSql/Internal/CommonExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@ internal string GetFieldAsCsName(string csname)
if (_common.CodeFirst.IsSyncStructureToUpper) csname = csname.ToUpper();
return csname;
}
public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Select0Provider select, BaseDiyMemberExpression diymemexp, List<GlobalFilter.Item> whereGlobalFilter, List<string> findIncludeMany, bool isAllDtoMap)
public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Select0Provider select,
BaseDiyMemberExpression diymemexp, List<GlobalFilter.Item> whereGlobalFilter, List<string> findIncludeMany, List<Expression> findSubSelectMany, bool isAllDtoMap)
{
Func<ExpTSC> getTSC = () => new ExpTSC { _tables = _tables, diymemexp = diymemexp, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter, dbParams = select?._params }; //#462 添加 DbParams 解决
switch (exp.NodeType)
{
case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap);
case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap);
case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, isAllDtoMap);
case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, isAllDtoMap);
case ExpressionType.Negate:
case ExpressionType.NegateChecked:
parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})";
Expand All @@ -61,7 +62,7 @@ public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder fiel
else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(GetFieldAsCsName(parent.CsName)));
if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type;
return false;
case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap);
case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, isAllDtoMap);
case ExpressionType.Constant:
var constExp = exp as ConstantExpression;
//处理自定义SQL语句,如: ToList(new {
Expand All @@ -84,10 +85,17 @@ public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder fiel
case ExpressionType.Conditional:
var condExp = exp as ConditionalExpression;
if (condExp.Test.IsParameter() == false) return ReadAnonymousField(_tables, field, parent, ref index,
(bool)Expression.Lambda(condExp.Test).Compile().DynamicInvoke() ? condExp.IfTrue : condExp.IfFalse, select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap);
(bool)Expression.Lambda(condExp.Test).Compile().DynamicInvoke() ? condExp.IfTrue : condExp.IfFalse, select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, isAllDtoMap);
break;
case ExpressionType.Call:
var callExp = exp as MethodCallExpression;
if (callExp.Method.Name == "ToList" && callExp.Object?.Type.FullName.StartsWith("FreeSql.ISelect`") == true)
{
parent.SubSelectMany = exp;
parent.CsType = exp.Type.GetGenericArguments().FirstOrDefault();
findSubSelectMany?.Add(exp);
return false;
}
//处理自定义SQL语句,如: ToList(new {
// ccc = Convert.ToDateTime("now()"),
// partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)")
Expand Down Expand Up @@ -157,7 +165,7 @@ public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder fiel
MapType = memProp.PropertyType
};
parent.Childs.Add(child);
ReadAnonymousField(_tables, field, child, ref index, Expression.MakeMemberAccess(exp, memProp), select, diymemexp, whereGlobalFilter, findIncludeMany, false);
ReadAnonymousField(_tables, field, child, ref index, Expression.MakeMemberAccess(exp, memProp), select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, false);
}
}
}
Expand Down Expand Up @@ -231,7 +239,7 @@ public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder fiel
MapType = initExp.NewExpression.Arguments[a].Type
};
parent.Childs.Add(child);
ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], select, diymemexp, whereGlobalFilter, findIncludeMany, false);
ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, false);
}
}
else if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type)
Expand All @@ -256,7 +264,7 @@ public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder fiel
};
parent.Childs.Add(child);
if (dtTb.Parameter != null)
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap);
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, isAllDtoMap);
else
{
child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}";
Expand All @@ -283,7 +291,7 @@ public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder fiel
};
if (child.Property == null) child.ReflectionField = initExp.Type.GetField(initExp.Bindings[a].Member.Name, BindingFlags.Public | BindingFlags.Instance);
parent.Childs.Add(child);
ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, select, diymemexp, whereGlobalFilter, findIncludeMany, false);
ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, false);
}
}
if (parent.Childs.Any() == false) throw new Exception(CoreStrings.Mapping_Exception_HasNo_SamePropertyName(initExp.NewExpression.Type.Name));
Expand Down Expand Up @@ -316,7 +324,7 @@ public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder fiel
MapType = newExp.Arguments[a].Type
};
parent.Childs.Add(child);
ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], select, diymemexp, whereGlobalFilter, findIncludeMany, false);
ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, false);
}
}
else
Expand All @@ -340,7 +348,7 @@ public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder fiel
};
parent.Childs.Add(child);
if (dtTb.Parameter != null)
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap);
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, isAllDtoMap);
else
{
child.DbField = _common.RereadColumn(trydtocol, $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}");
Expand All @@ -361,9 +369,10 @@ public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder fiel
if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type;
return false;
}
public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead, ReadAnonymousDbValueRef dbValue, int rowIndex, List<NativeTuple<string, IList, int>> fillIncludeMany)
public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead, ReadAnonymousDbValueRef dbValue, int rowIndex,
List<NativeTuple<string, IList, int>> fillIncludeMany, List<NativeTuple<Expression, IList, int>> fillSubSelectMany)
{
if (parent.Childs.Any() == false && string.IsNullOrEmpty(parent.IncludeManyKey))
if (parent.Childs.Any() == false && string.IsNullOrEmpty(parent.IncludeManyKey) && parent.SubSelectMany == null)
{
if (notRead)
{
Expand All @@ -389,21 +398,26 @@ public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref i
ret = typeof(List<>).MakeGenericType(parent.CsType).CreateInstanceGetDefaultValue();
fillIncludeMany?.Add(NativeTuple.Create(parent.IncludeManyKey, ret as IList, rowIndex));
}
else if (parent.SubSelectMany != null)
{
ret = typeof(List<>).MakeGenericType(parent.CsType).CreateInstanceGetDefaultValue();
fillSubSelectMany?.Add(NativeTuple.Create(parent.SubSelectMany, ret as IList, rowIndex));
}
else if (parent.IsDefaultCtor || parent.IsEntity || (ctorParmsLength = parent.Consturctor.GetParameters()?.Length ?? 0) == 0)
ret = parent.CsType?.CreateInstanceGetDefaultValue() ?? parent.Consturctor.Invoke(null);
else
{
var ctorParms = new object[ctorParmsLength];
for (var c = 0; c < ctorParmsLength; c++)
ctorParms[c] = ReadAnonymous(parent.Childs[c], dr, ref index, notRead, null, rowIndex, fillIncludeMany);
ctorParms[c] = ReadAnonymous(parent.Childs[c], dr, ref index, notRead, null, rowIndex, fillIncludeMany, fillSubSelectMany);
ret = parent.Consturctor.Invoke(ctorParms);
}

var isnull = notRead;
for (var b = ctorParmsLength; b < parent.Childs.Count; b++)
{
var dbval = parent.IsEntity ? new ReadAnonymousDbValueRef() : null;
var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead, dbval, rowIndex, fillIncludeMany);
var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead, dbval, rowIndex, fillIncludeMany, fillSubSelectMany);
if (isnull == false && parent.IsEntity && dbval.DbValue == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary)
isnull = true;

Expand Down Expand Up @@ -1262,7 +1276,7 @@ public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc)
var index = -1;

for (var a = 0; a < exp3Args0.Parameters.Count; a++) fsqls0p._tables[a].Parameter = exp3Args0.Parameters[a];
ReadAnonymousField(fsqls0p._tables, field, map, ref index, exp3Args0, null, null, null, null, false);
ReadAnonymousField(fsqls0p._tables, field, map, ref index, exp3Args0, null, null, null, null, null, false);
var fieldSql = field.Length > 0 ? field.Remove(0, 2).ToString() : null;

var sql4 = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { $"{exp3.Method.Name.ToLower()}({fieldSql})" })?.ToString();
Expand Down Expand Up @@ -2134,7 +2148,7 @@ void LocalInitSelectProvider()
var field = new StringBuilder();
var index = -1;

commonExp.ReadAnonymousField(select._tables, field, map, ref index, callExp.Arguments[1], null, null, null, null, false);
commonExp.ReadAnonymousField(select._tables, field, map, ref index, callExp.Arguments[1], null, null, null, null, null, false);
var fieldSql = field.Length > 0 ? field.Remove(0, 2).ToString() : null;

e.Result = commonExp._common.IsNull($"({select.ToSql($"{aggregateMethodName}({fieldSql})").Replace(" \r\n", " \r\n ")})", 0);
Expand Down
Loading

0 comments on commit fbbc043

Please sign in to comment.