mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-11-07 18:04:55 +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 SchoolA() { SchoolId = 1, School_Name = "北大" }).ExecuteCommand();
|
||||
db.Insertable(new SchoolA() { SchoolId = 2, School_Name = "清华" }).ExecuteCommand();
|
||||
db.Insertable(new SchoolA() { SchoolId = 1, CityId= 1001001, 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 = 2, SchoolId = 1, Name = "北大tom" }).ExecuteCommand();
|
||||
@@ -65,6 +65,16 @@ namespace OrmTest
|
||||
.Mapper(it => it.SchoolA, it => it.SchoolId)
|
||||
.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>()
|
||||
.Includes(x => x.SchoolA, x => x.RoomList)//2个参数就是 then Include
|
||||
@@ -220,14 +230,19 @@ namespace OrmTest
|
||||
}
|
||||
public class SchoolA
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
[SugarColumn(IsPrimaryKey = true,ColumnName = "schoolid")]
|
||||
public int SchoolId { get; set; }
|
||||
[SugarColumn(IsNullable =true)]
|
||||
public int CityId { get; set; }
|
||||
[SugarColumn( ColumnName = "SchoolName")]
|
||||
public string School_Name { get; set; }
|
||||
[Navigate(NavigateType.OneToMany,nameof(RoomA.SchoolId))]
|
||||
public List<RoomA> RoomList { get; set; }
|
||||
[Navigate(NavigateType.OneToMany, nameof(TeacherA.SchoolId))]
|
||||
public List<TeacherA> TeacherList { get; set; }
|
||||
[Navigate(NavigateType.OneToOne,nameof(CityId))]
|
||||
public City City { get; set; }
|
||||
|
||||
}
|
||||
public class TeacherA
|
||||
{
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace SqlSugar
|
||||
else if (isMemberValue)
|
||||
{
|
||||
var nav = new OneToOneNavgateExpression(this.Context?.SugarContext?.Context);
|
||||
var navN = new OneToOneNavgateExpressionN(this.Context?.SugarContext?.Context);
|
||||
if (nav.IsNavgate(expression))
|
||||
{
|
||||
var value = nav.GetSql();
|
||||
@@ -72,6 +73,19 @@ namespace SqlSugar
|
||||
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
|
||||
{
|
||||
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="Entities\SugarConnection.cs" />
|
||||
<Compile Include="ExpressionsToSql\Common\ExpressionOutParameter.cs" />
|
||||
<Compile Include="ExpressionsToSql\ResolveItems\NavgateExpressionCall.cs" />
|
||||
<Compile Include="ExpressionsToSql\ResolveItems\NavgateExpression.cs" />
|
||||
<Compile Include="ExpressionsToSql\ResolveItems\OneToManyNavgateExpression.cs" />
|
||||
<Compile Include="ExpressionsToSql\ResolveItems\OneToOneNavgateExpressionN.cs" />
|
||||
<Compile Include="ExpressionsToSql\ResolveItems\OneToOneNavgateExpression.cs" />
|
||||
<Compile Include="ExpressionsToSql\Subquery\SubTemplate.cs" />
|
||||
<Compile Include="ExpressionsToSql\Subquery\SubqueryableN.cs" />
|
||||
<Compile Include="Abstract\QueryableProvider\QueryableContext.cs" />
|
||||
|
||||
Reference in New Issue
Block a user