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) customName2 = SqlFunc.Subqueryable<Custom>().Where("it.CustomId = id").Where(s => true).Select(s => s.Name)
}).ToList(); }).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 ####"); Console.WriteLine("#### Subquery End ####");
} }

View File

@ -196,6 +196,9 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="UnitTest\models\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- 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. 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 = 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); return _Mapper<TObject>(mapperObject, mapperField);
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -9,6 +9,16 @@ namespace SqlSugar
public class Subqueryable<T> where T : class, new() 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) public Subqueryable<T> Where(string where)
{ {
return this; 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 // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("5.0.1.7")] [assembly: AssemblyVersion("5.0.1.8")]
[assembly: AssemblyFileVersion("5.0.1.7")] [assembly: AssemblyFileVersion("5.0.1.8")]

View File

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