SubQuery support join

This commit is contained in:
skx 2020-12-29 13:06:45 +08:00
parent 6e0078a905
commit f17754c6f9
12 changed files with 99 additions and 7 deletions

View File

@ -122,7 +122,11 @@ namespace OrmTest
customName2 = SqlFunc.Subqueryable<Custom>().Where("it.CustomId = id").Where(s => true).Select(s => s.Name)
}).ToList();
var list2 = db.Queryable<Order>().Where(it => SqlFunc.Subqueryable<OrderItem>().Where(i => i.OrderId == it.Id).Any()).ToList();
var list2 = db.Queryable<Order>().Where(it =>
SqlFunc.Subqueryable<OrderItem>()
.LeftJoin<OrderItem>((i,y)=>i.ItemId==y.ItemId)
.Where<OrderItem>((i,y) => y.ItemId== it.Id).Any()
).ToList();
Console.WriteLine("#### Subquery End ####");
}

View File

@ -196,6 +196,9 @@
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="UnitTest\models\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -132,7 +132,7 @@ namespace SqlSugar
{
CallContext.MapperExpression.Value = new List<MapperExpression>();
}
CallContext.MapperExpression.Value.Add(new MapperExpression() { QueryBuilder = this.QueryBuilder, Type=MapperExpressionType.oneToOne, FillExpression=mapperObject, MappingField1Expression= mapperField,Context=this.Context });
CallContext.MapperExpression.Value.Add(new MapperExpression() { SqlBuilder= SqlBuilder, QueryBuilder = this.QueryBuilder, Type=MapperExpressionType.oneToOne, FillExpression=mapperObject, MappingField1Expression= mapperField,Context=this.Context });
return _Mapper<TObject>(mapperObject, mapperField);
}

View File

@ -69,6 +69,10 @@ namespace SqlSugar
public virtual string GetTranslationColumnName(string propertyName)
{
if (propertyName.Contains(SqlTranslationLeft)) return propertyName;
if (propertyName.Contains("."))
{
return string.Join(".", propertyName.Split('.').Select(it => SqlTranslationLeft + it + SqlTranslationRight));
}
else
return SqlTranslationLeft + propertyName + SqlTranslationRight;
}

View File

@ -15,6 +15,7 @@ namespace SqlSugar
public Expression MappingField2Expression { get; set; }
public SqlSugarProvider Context { get; set; }
public QueryBuilder QueryBuilder { get; set; }
public ISqlBuilder SqlBuilder { get; set; }
}
public enum MapperExpressionType

View File

@ -36,6 +36,7 @@ namespace SqlSugar
}
}
public int SubQueryIndex { get; set; }
public int JoinIndex { get; set; }
public int Index { get; set; }
public int ParameterIndex { get; set; }
public string SingleTableNameSubqueryShortName{ get; set; }

View File

@ -12,6 +12,7 @@ namespace SqlSugar
private InvalidOperationException ex;
private SqlSugarProvider context;
private QueryBuilder querybuiler;
private ISqlBuilder sqlBuilder;
private string sql;
public MapperExpressionResolve(Expression expression, InvalidOperationException ex)
{
@ -77,10 +78,13 @@ namespace SqlSugar
{
pkColumn = selectInfo.EntityInfo.Columns.First();
}
var tableName = sqlBuilder.GetTranslationTableName(fillInfo.EntityInfo.DbTableName);
var whereLeft = sqlBuilder.GetTranslationColumnName(pkColumn.DbColumnName);
var whereRight = sqlBuilder.GetTranslationColumnName(mappingFild1Info.FieldString);
this.sql = this.context.Queryable<object>()
.AS(fillInfo.EntityInfo.DbTableName)
.Where(string.Format(" {0}={1} ", pkColumn.DbColumnName, mappingFild1Info.FieldString))
.Select(selectInfo.FieldName).ToSql().Key;
.AS(tableName)
.Where(string.Format(" {0}={1} ",whereLeft , whereRight))
.Select(sqlBuilder.GetTranslationColumnName(selectInfo.FieldName)).ToSql().Key;
}
private void oneToMany()
@ -160,6 +164,7 @@ namespace SqlSugar
{
this.querybuiler = mapper.QueryBuilder;
this.context = mapper.Context;
this.sqlBuilder = mapper.SqlBuilder;
if (this.querybuiler.TableShortName.IsNullOrEmpty())
{
this.querybuiler.TableShortName = (childExpression as MemberExpression).Expression.ToString();

View File

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace SqlSugar
{
public class SubLeftJoin : ISubOperation
{
public bool HasWhere
{
get; set;
}
public string Name
{
get { return "LeftJoin"; }
}
public Expression Expression
{
get; set;
}
public int Sort
{
get
{
return 301;
}
}
public ExpressionContext Context
{
get; set;
}
public string GetValue(Expression expression)
{
var exp = expression as MethodCallExpression;
var argExp = exp.Arguments[0];
var name =this.Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters[0].Name);
var parameter = (argExp as LambdaExpression).Parameters[1];
Context.InitMappingInfo(parameter.Type);
var tableName= Context.GetTranslationTableName(parameter.Type.Name, true);
var joinString =string.Format(" {2} LEFT JOIN {1} {0} ",
this.Context.GetTranslationColumnName(parameter.Name),
tableName,
this.Context.JoinIndex==0?name:"");
var result = joinString+ "ON " + SubTools.GetMethodValue(Context, argExp, ResolveExpressType.WhereMultiple);
//var selfParameterName = Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters.First().Name) + UtilConstants.Dot;
this.Context.JoinIndex++;
//result = result.Replace(selfParameterName, SubTools.GetSubReplace(this.Context));
return result;
}
}
}

View File

@ -16,6 +16,7 @@ namespace SqlSugar
new SubSelect() { Context=Context },
new SubWhere(){ Context=Context },
new SubWhereIF(){ Context=Context },
new SubLeftJoin(){ Context=Context },
new SubAnd(){ Context=Context },
new SubAndIF(){ Context=Context },
new SubAny(){ Context=Context },

View File

@ -9,6 +9,16 @@ namespace SqlSugar
public class Subqueryable<T> where T : class, new()
{
public Subqueryable<T> InnerJoin<JoinType>(Func<T, JoinType, bool> expression)
{
return this;
}
public Subqueryable<T> LeftJoin<JoinType>(Func<T, JoinType, bool> expression)
{
return this;
}
public Subqueryable<T> Where(string where)
{
return this;

View File

@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("5.0.1.7")]
[assembly: AssemblyFileVersion("5.0.1.7")]
[assembly: AssemblyVersion("5.0.1.8")]
[assembly: AssemblyFileVersion("5.0.1.8")]

View File

@ -92,6 +92,7 @@
<Compile Include="Entities\SubInsertTree.cs" />
<Compile Include="ExpressionsToSql\Common\MapperExpression.cs" />
<Compile Include="ExpressionsToSql\ResolveItems\MapperExpressionResolve.cs" />
<Compile Include="ExpressionsToSql\Subquery\Items\SubLeftJoin.cs" />
<Compile Include="OnlyNet\Compatible.cs" />
<Compile Include="OnlyNet\KdbndpInserttable.cs" />
<Compile Include="Interface\ISubInsertable.cs" />