mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-11-08 02:14:53 +08:00
Update navgate query
This commit is contained in:
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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" />
|
||||||
|
|||||||
Reference in New Issue
Block a user