Update navgate query

This commit is contained in:
sunkaixuan
2022-05-01 20:47:28 +08:00
parent d7f90075f7
commit d6e595292d
4 changed files with 212 additions and 5 deletions

View File

@@ -30,8 +30,8 @@ namespace OrmTest
db.Insertable(new RoomA() { RoomId = 6, RoomName = "清华003厅", SchoolId = 2 }).ExecuteCommand(); db.Insertable(new RoomA() { RoomId = 6, RoomName = "清华003厅", SchoolId = 2 }).ExecuteCommand();
db.Insertable(new SchoolA() { SchoolId = 1, School_Name = "北大" }).ExecuteCommand(); db.Insertable(new SchoolA() { SchoolId = 1, CityId= 1001001, School_Name = "北大" }).ExecuteCommand();
db.Insertable(new SchoolA() { SchoolId = 2, School_Name = "清华" }).ExecuteCommand(); db.Insertable(new SchoolA() { SchoolId = 2 , CityId=2,School_Name = "清华" }).ExecuteCommand();
db.Insertable(new StudentA() { StudentId = 1, SchoolId = 1, Name = "北大jack" }).ExecuteCommand(); db.Insertable(new StudentA() { StudentId = 1, SchoolId = 1, Name = "北大jack" }).ExecuteCommand();
db.Insertable(new StudentA() { StudentId = 2, SchoolId = 1, Name = "北大tom" }).ExecuteCommand(); db.Insertable(new StudentA() { StudentId = 2, SchoolId = 1, Name = "北大tom" }).ExecuteCommand();
@@ -65,6 +65,16 @@ namespace OrmTest
.Mapper(it => it.SchoolA, it => it.SchoolId) .Mapper(it => it.SchoolA, it => it.SchoolId)
.ToList(); .ToList();
var list22 = db.Queryable<StudentA>()
//.Includes(it => it.SchoolA)
.Where(it=>it.SchoolA.City.Id== 1001001)
.ToList();
var list33 = db.Queryable<StudentA>()
//.Includes(it => it.SchoolA)
.Where(it => it.SchoolA.SchoolId == 1)
.ToList();
Check.Exception(string.Join(",", list22.Select(it => it.StudentId)) != string.Join(",", list33.Select(it => it.StudentId)), "unit error");
var list3 = db.Queryable<StudentA>() var list3 = db.Queryable<StudentA>()
.Includes(x => x.SchoolA, x => x.RoomList)//2个参数就是 then Include .Includes(x => x.SchoolA, x => x.RoomList)//2个参数就是 then Include
@@ -220,14 +230,19 @@ namespace OrmTest
} }
public class SchoolA public class SchoolA
{ {
[SugarColumn(IsPrimaryKey = true)] [SugarColumn(IsPrimaryKey = true,ColumnName = "schoolid")]
public int SchoolId { get; set; } public int SchoolId { get; set; }
[SugarColumn(IsNullable =true)]
public int CityId { get; set; }
[SugarColumn( ColumnName = "SchoolName")] [SugarColumn( ColumnName = "SchoolName")]
public string School_Name { get; set; } public string School_Name { get; set; }
[Navigate(NavigateType.OneToMany,nameof(RoomA.SchoolId))] [Navigate(NavigateType.OneToMany,nameof(RoomA.SchoolId))]
public List<RoomA> RoomList { get; set; } public List<RoomA> RoomList { get; set; }
[Navigate(NavigateType.OneToMany, nameof(TeacherA.SchoolId))] [Navigate(NavigateType.OneToMany, nameof(TeacherA.SchoolId))]
public List<TeacherA> TeacherList { get; set; } public List<TeacherA> TeacherList { get; set; }
[Navigate(NavigateType.OneToOne,nameof(CityId))]
public City City { get; set; }
} }
public class TeacherA public class TeacherA
{ {

View File

@@ -59,6 +59,7 @@ namespace SqlSugar
else if (isMemberValue) else if (isMemberValue)
{ {
var nav = new OneToOneNavgateExpression(this.Context?.SugarContext?.Context); var nav = new OneToOneNavgateExpression(this.Context?.SugarContext?.Context);
var navN = new OneToOneNavgateExpressionN(this.Context?.SugarContext?.Context);
if (nav.IsNavgate(expression)) if (nav.IsNavgate(expression))
{ {
var value = nav.GetSql(); var value = nav.GetSql();
@@ -72,6 +73,19 @@ namespace SqlSugar
AppendValue(parameter, isLeft, value); AppendValue(parameter, isLeft, value);
} }
} }
else if (navN.IsNavgate(expression))
{
var value = navN.GetMemberSql();
this.Context.SingleTableNameSubqueryShortName = navN.shorName;
if (isSetTempData)
{
baseParameter.CommonTempData = value;
}
else
{
AppendValue(parameter, isLeft, value);
}
}
else else
{ {
ResolveMemberValue(parameter, baseParameter, isLeft, isSetTempData, expression); ResolveMemberValue(parameter, baseParameter, isLeft, isSetTempData, expression);

View File

@@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar
{
internal class OneToOneNavgateExpressionN
{
#region Constructor
public string shorName { get; set; }
public EntityInfo entityInfo;
public SqlSugarProvider context;
public OneToOneNavgateExpressionN(SqlSugarProvider context)
{
this.context = context;
}
public bool IsNavgate(Expression expression)
{
var result = false;
var exp = expression;
if (exp is UnaryExpression)
{
exp = (exp as UnaryExpression).Operand;
}
if (exp is MemberExpression)
{
var memberExp = exp as MemberExpression;
var childExpression = memberExp.Expression;
result = ValidateIsJoinMember(result, memberExp, childExpression);
}
else if (exp is MethodCallExpression)
{
var memberExp = exp as MemberExpression;
var childExpression = memberExp.Expression;
result = ValidateIsJoinAny(result, memberExp, childExpression);
}
return result;
}
public MapperSql GetMemberSql()
{
MapperSql MapperSql = new MapperSql();
var memberInfo = this.items.Where(it => it.Type == 1).First();
var subInfos = this.items.Where(it => it.Type == 2).Reverse().ToList();
var formInfo = subInfos.First();
var joinInfos = subInfos.Skip(1).ToList();
var i = 0;
var masterShortName = formInfo.ThisEntityInfo.DbTableName + i;
var queryable = this.context.Queryable<object>(masterShortName).AS(formInfo.ThisEntityInfo.DbTableName);
i++;
var lastShortName = "";
foreach (var item in joinInfos)
{
var shortName = item.ThisEntityInfo.DbTableName+i;
var pkColumn = item.ThisEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey);
var navColum = item.ParentEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == item.Nav.Name);
Check.ExceptionEasy(pkColumn == null, $"{item.ThisEntityInfo.EntityName} need PrimayKey", $"使用导航属性{item.ThisEntityInfo.EntityName} 缺少主键");
var on = $" {shortName}.{pkColumn.DbColumnName}={formInfo.ThisEntityInfo.DbTableName + (i-1)}.{navColum.DbColumnName}";
queryable.AddJoinInfo(item.ThisEntityInfo.DbTableName, shortName,on , JoinType.Inner);
++i;
lastShortName=shortName;
formInfo = item;
}
var selectProperyInfo=ExpressionTool.GetMemberName(memberInfo.Expression);
var selectColumnInfo = memberInfo.ParentEntityInfo.Columns.First(it => it.PropertyName == selectProperyInfo);
queryable.Select($" {lastShortName}.{selectColumnInfo.DbColumnName}");
var last = subInfos.First();
var FirstPkColumn = last.ThisEntityInfo.Columns.FirstOrDefault(it =>it.IsPrimarykey);
Check.ExceptionEasy(FirstPkColumn == null, $"{ last.ThisEntityInfo.EntityName} need PrimayKey", $"使用导航属性{ last.ThisEntityInfo.EntityName} 缺少主键");
var PkColumn = last.ParentEntityInfo.Columns.FirstOrDefault(it => it.PropertyName==last.Nav.Name);
Check.ExceptionEasy(PkColumn == null, $"{ last.ParentEntityInfo.EntityName} no found {last.Nav.Name}", $"{ last.ParentEntityInfo.EntityName} 不存在 {last.Nav.Name}");
queryable.Where($" {this.shorName}.{PkColumn.DbColumnName} = {masterShortName}.{FirstPkColumn.DbColumnName} ");
MapperSql.Sql ="( " + queryable.ToSql().Key+" ) ";
return MapperSql;
}
#endregion
#region All one to one
List<ExpressionItems> items;
private bool ValidateIsJoinMember(bool result, MemberExpression memberExp, Expression childExpression)
{
if (childExpression != null && childExpression is MemberExpression)
{
var oldChildExpression = childExpression;
var child2Expression = (childExpression as MemberExpression).Expression;
if (child2Expression == null)
{
return false;
}
items = new List<ExpressionItems>();
items.Add(new ExpressionItems() { Type=1 , Expression= memberExp, ParentEntityInfo= this.context.EntityMaintenance.GetEntityInfo(oldChildExpression.Type )});
items.Add(new ExpressionItems() { Type = 2, Expression = oldChildExpression, ThisEntityInfo=this.context.EntityMaintenance.GetEntityInfo(oldChildExpression.Type), ParentEntityInfo = this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type) });
while (child2Expression != null)
{
if (IsClass(child2Expression))
{
items.Add(new ExpressionItems() { Type = 2, Expression = child2Expression, ThisEntityInfo=this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type), ParentEntityInfo = this.context.EntityMaintenance.GetEntityInfo(GetMemberExpression(child2Expression).Type) });
child2Expression = GetMemberExpression(child2Expression);
}
else if (IsParameter(child2Expression))
{
shorName = child2Expression.ToString();
entityInfo = this.context.EntityMaintenance.GetEntityInfo(child2Expression.Type);
break;
}
else
{
break;
}
}
if (!items.Any(it => it.Type == 2 && it.Nav == null))
{
return true;
}
}
return result;
}
#endregion
#region One to one Last Method
private bool ValidateIsJoinAny(bool result, MemberExpression memberExp, Expression childExpression)
{
return false;
}
#endregion
#region Helper
private static bool IsParameter(Expression child2Expression)
{
return child2Expression.Type.IsClass() && child2Expression is ParameterExpression;
}
private static Expression GetMemberExpression(Expression child2Expression)
{
return (child2Expression as MemberExpression).Expression;
}
private static bool IsClass(Expression child2Expression)
{
return child2Expression.Type.IsClass() && child2Expression is MemberExpression;
}
#endregion
#region Entities
internal class ExpressionItems
{
/// <summary>
/// 0 memeber, 2 method ,3 class
/// </summary>
public int Type { get; set; }
public EntityInfo ParentEntityInfo { get; set; }
public EntityInfo ThisEntityInfo { get; set; }
public Expression Expression { get; set; }
public Navigate Nav
{
get
{
if (Expression is MemberExpression)
{
var name=(Expression as MemberExpression).Member.Name;
var navColumn = ParentEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == name);
return navColumn==null?null:navColumn.Navigat;
}
return null;
}
}
}
#endregion
}
}

View File

@@ -108,8 +108,9 @@
<Compile Include="Enum\SugarActionType.cs" /> <Compile Include="Enum\SugarActionType.cs" />
<Compile Include="Entities\SugarConnection.cs" /> <Compile Include="Entities\SugarConnection.cs" />
<Compile Include="ExpressionsToSql\Common\ExpressionOutParameter.cs" /> <Compile Include="ExpressionsToSql\Common\ExpressionOutParameter.cs" />
<Compile Include="ExpressionsToSql\ResolveItems\NavgateExpressionCall.cs" /> <Compile Include="ExpressionsToSql\ResolveItems\OneToManyNavgateExpression.cs" />
<Compile Include="ExpressionsToSql\ResolveItems\NavgateExpression.cs" /> <Compile Include="ExpressionsToSql\ResolveItems\OneToOneNavgateExpressionN.cs" />
<Compile Include="ExpressionsToSql\ResolveItems\OneToOneNavgateExpression.cs" />
<Compile Include="ExpressionsToSql\Subquery\SubTemplate.cs" /> <Compile Include="ExpressionsToSql\Subquery\SubTemplate.cs" />
<Compile Include="ExpressionsToSql\Subquery\SubqueryableN.cs" /> <Compile Include="ExpressionsToSql\Subquery\SubqueryableN.cs" />
<Compile Include="Abstract\QueryableProvider\QueryableContext.cs" /> <Compile Include="Abstract\QueryableProvider\QueryableContext.cs" />