Add Subquery.First()

This commit is contained in:
sunkaixuan 2023-03-12 17:16:41 +08:00
parent 3eb4c19bf6
commit 1e2af87f5d
7 changed files with 185 additions and 9 deletions

View File

@ -1693,7 +1693,13 @@ namespace SqlSugar
{
var ps = this.QueryBuilder.Parameters;
var itemProperty = typeof(TResult).GetProperty(subPara.Key);
var callType = itemProperty.PropertyType.GetGenericArguments()[0];
var callType = itemProperty.PropertyType.GetGenericArguments().FirstOrDefault();
var isFirst = false;
if (callType == null)
{
callType = itemProperty.PropertyType;
isFirst = true;
}
var sql = subPara.Value.ObjToString().Replace("@sugarIndex", "0");
sql =SqlBuilder.RemoveParentheses(sql);
var methodParamters = new object[] { sql, ps };
@ -1711,7 +1717,14 @@ namespace SqlSugar
}
else
{
itemProperty.SetValue(item, subList);
if (isFirst)
{
itemProperty.SetValue(item, (subList as IList)[0] );
}
else
{
itemProperty.SetValue(item, subList);
}
}
}
}
@ -1741,10 +1754,14 @@ namespace SqlSugar
index++;
}
var itemProperty = typeof(TResult).GetProperty(subPara.Key);
var callType = itemProperty.PropertyType.GetGenericArguments()[0];
var callType = itemProperty.PropertyType.GetGenericArguments().FirstOrDefault();
var isFirst = false;
if (callType == null)
{
callType = itemProperty.PropertyType;
isFirst = true;
}
var sqlstring = string.Join(" \r\n UNION ALL ", sqls);
var methodParamters = new object[] { sqlstring, ps.ToArray() };
this.QueryBuilder.SubToListParameters = null;
@ -1755,7 +1772,11 @@ namespace SqlSugar
var subList = ExpressionBuilderHelper.CallFunc(callType, methodParamters, this.Clone(), "SubQueryList");
var appendValue = this.QueryBuilder.AppendValues;
var list = (subList as IEnumerable).Cast<object>().ToList();
if (typeof(TResult).IsAnonymousType())
if (isFirst)
{
SetSubListWithClassFirst(result, itemProperty, appendValue, list, 0);
}
else if (typeof(TResult).IsAnonymousType())
{
SetSubListWithAnonymousType(result, itemProperty, appendValue, list, 0);
}
@ -1791,6 +1812,30 @@ namespace SqlSugar
}
return resIndex;
}
private static int SetSubListWithClassFirst<TResult>(List<TResult> result, PropertyInfo itemProperty, List<List<QueryableAppendColumn>> appendValue, List<object> list, int resIndex)
{
foreach (var item in result)
{
//var setValue = Activator.CreateInstance(itemProperty.PropertyType, true);
if (appendValue != null)
{
var appindex = 0;
foreach (var appValue in appendValue)
{
if (appValue[0].Value.ObjToInt() == resIndex)
{
var addItem = list[appindex];
itemProperty.SetValue(item, addItem);
}
appindex++;
}
}
//itemProperty.SetValue(item, setValue);
resIndex++;
}
return resIndex;
}
private static int SetSubListWithClass<TResult>(List<TResult> result, PropertyInfo itemProperty, List<List<QueryableAppendColumn>> appendValue, List<object> list, int resIndex)
{

View File

@ -14,7 +14,7 @@ namespace SqlSugar
private static bool IsSubToList(Expression item)
{
return ExpressionTool.GetMethodName(item) == "ToList" && IsSubquery(item);
return ExpressionTool.GetMethodName(item).IsIn("ToList","First") && IsSubquery(item);
}
private static bool IsSubquery(Expression item)

View File

@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar
{
public class SubFirst : ISubOperation
{
public bool HasWhere
{
get; set;
}
public string Name
{
get
{
return "First";
}
}
public Expression Expression
{
get; set;
}
public int Sort
{
get
{
return 200;
}
}
public ExpressionContext Context
{
get; set;
}
public string GetValue(Expression expression = null)
{
;
var exp = expression as MethodCallExpression;
InitType(exp);
var type = expression.Type;
if (type.FullName.IsCollectionsList()
&& exp.Arguments.Count == 0 && type.GenericTypeArguments.Length > 0
&& this.Context.SugarContext != null
&& this.Context.SugarContext.QueryBuilder.IsSelectNoAll)
{
var entity = type.GenericTypeArguments[0];
var columnNames = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(entity).Columns;
var columnsString = string.Join(",", columnNames
.Where(it => it.IsIgnore == false)
.Where(it => it.DbColumnName.HasValue())
.Select(it => this.Context.GetTranslationColumnName(it.DbColumnName)));
return $"{columnsString},@sugarIndex as sugarIndex";
}
else if (exp.Arguments.Count == 0)
{
return "*,@sugarIndex as sugarIndex";
}
var argExp = exp.Arguments[0];
var parametres = (argExp as LambdaExpression).Parameters;
if ((argExp as LambdaExpression).Body is UnaryExpression)
{
argExp = ((argExp as LambdaExpression).Body as UnaryExpression).Operand;
}
var argLambda = argExp as LambdaExpression;
var copyContext = this.Context.GetCopyContextWithMapping();
copyContext.Resolve(argLambda, ResolveExpressType.SelectMultiple);
var select = copyContext.Result.GetString();
this.Context.Parameters.AddRange(copyContext.Parameters);
this.Context.Index = copyContext.Index;
this.Context.ParameterIndex = copyContext.ParameterIndex;
SetShortName(exp, null);
return select + ",@sugarIndex as sugarIndex";
}
private void InitType(MethodCallExpression exp)
{
if (exp.Arguments.Count > 0)
{
foreach (var arg in (exp.Arguments[0] as LambdaExpression).Parameters)
{
if (this.Context.InitMappingInfo != null)
{
this.Context.InitMappingInfo(arg.Type);
this.Context.RefreshMapping();
}
}
}
}
public void SetShortName(MethodCallExpression exp, string result)
{
if (exp.Arguments[0] is LambdaExpression)
{
var parameters = (exp.Arguments[0] as LambdaExpression).Parameters;
if (parameters != null && parameters.Count > 0)
{
this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString());
}
}
}
public void SetShortNameNext(MethodCallExpression exp, string result)
{
if (exp.Arguments.Count > 1 && exp.Arguments[1] is LambdaExpression)
{
var parameters = (exp.Arguments[1] as LambdaExpression).Parameters;
if (parameters != null && parameters.Count > 0)
{
this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString());
}
}
}
}
}

View File

@ -223,7 +223,7 @@ namespace SqlSugar
}).ToList();
SetOrderByIndex(isubList);
isubList.Insert(0, new SubBegin());
if (isubList.Any(it => it is SubSelect))
if (isubList.Any(it => it is SubSelect||it is SubFirst))
{
isubList.Add(new SubTop() { Context = this.context });
}

View File

@ -38,7 +38,8 @@ namespace SqlSugar
new SubEnableTableFilter(){ Context=Context },
new SubSelectStringJoin{ Context=Context },
new SubDistinctCount{ Context=Context },
new SubToList{ Context=Context}
new SubToList{ Context=Context},
new SubFirst(){ Context=Context }
};
}

View File

@ -180,5 +180,10 @@ namespace SqlSugar
{
return null;
}
public T First()
{
return default(T);
}
}
}

View File

@ -154,6 +154,7 @@
<Compile Include="ExpressionsToSql\ResolveItems\MethodCallExpressionResolve_Helper.cs" />
<Compile Include="ExpressionsToSql\ResolveItems\MethodCallExpressionResolve_BaseDateFomat.cs" />
<Compile Include="ExpressionsToSql\Subquery\Items\SubDistinctCount.cs" />
<Compile Include="ExpressionsToSql\Subquery\Items\SubFirst.cs" />
<Compile Include="ExpressionsToSql\Subquery\Items\SubSelectStringJoin.cs" />
<Compile Include="ExpressionsToSql\Subquery\Items\SubToList.cs" />
<Compile Include="ExpressionsToSql\Subquery\Items\SubWithNoLock.cs" />