- 优化 ISelect.GroupBy 查询,增加 .Value 实现聚合源字段查询,ToList(a => a.Sum(a.Value.Score));

- 增加 Expression string.Concat;
This commit is contained in:
28810 2019-04-25 12:34:09 +08:00
parent ddd5e81a67
commit 02ab4949c0
44 changed files with 466 additions and 86 deletions

View File

@ -726,7 +726,59 @@ namespace FreeSql.Tests.MySql {
arg1 = a.Avg(a.Key.mod4), arg1 = a.Avg(a.Key.mod4),
ccc2 = a.Key.tt2 ?? "now()", ccc2 = a.Key.tt2 ?? "now()",
//ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)")
ccc3 = a.Max(a.Value.Item3.Id)
}); });
var testpid1 = g.mysql.Insert<TestTypeInfo>().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity();
g.mysql.Insert<TestInfo>().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows();
var aggsql1 = select
.GroupBy(a => a.Title)
.ToSql(b => new {
b.Key,
cou = b.Count(),
sum = b.Sum(b.Key),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggtolist1 = select
.GroupBy(a => a.Title)
.ToList(b => new {
b.Key,
cou = b.Count(),
sum = b.Sum(b.Key),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggsql2 = select
.GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) })
.ToSql(b => new {
b.Key.Title,
b.Key.yyyy,
cou = b.Count(),
sum = b.Sum(b.Key.yyyy),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggtolist2 = select
.GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) })
.ToList(b => new {
b.Key.Title,
b.Key.yyyy,
cou = b.Count(),
sum = b.Sum(b.Key.yyyy),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggsql3 = select
.GroupBy(a => a.Title)
.ToSql(b => new {
b.Key,
cou = b.Count(),
sum = b.Sum(b.Key),
sum2 = b.Sum(b.Value.TypeGuid),
sum3 = b.Sum(b.Value.Type.Parent.Id)
});
} }
[Fact] [Fact]
public void ToAggregate() { public void ToAggregate() {

View File

@ -1,4 +1,5 @@
using FreeSql.DataAnnotations; using FreeSql.DataAnnotations;
using MySql.Data.MySqlClient;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -16,6 +17,10 @@ namespace FreeSql.Tests.MySqlExpression {
[Fact] [Fact]
public void Array() { public void Array() {
int[] nullarr = null;
Assert.Throws<MySqlException>(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); });
Assert.Throws<MySqlException>(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); });
//in not in //in not in
var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList();

View File

@ -622,7 +622,59 @@ namespace FreeSql.Tests.Oracle {
arg1 = a.Avg(a.Key.mod4), arg1 = a.Avg(a.Key.mod4),
ccc2 = a.Key.tt2 ?? "now()", ccc2 = a.Key.tt2 ?? "now()",
//ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)")
ccc3 = a.Max(a.Value.Item3.Id)
}); });
var testpid1 = g.oracle.Insert<TestTypeInfo>().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity();
g.oracle.Insert<TestInfo>().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows();
var aggsql1 = select
.GroupBy(a => a.Title)
.ToSql(b => new {
b.Key,
cou = b.Count(),
sum = b.Sum(b.Key),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggtolist1 = select
.GroupBy(a => a.Title)
.ToList(b => new {
b.Key,
cou = b.Count(),
sum = b.Sum(b.Key),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggsql2 = select
.GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) })
.ToSql(b => new {
b.Key.Title,
b.Key.yyyy,
cou = b.Count(),
sum = b.Sum(b.Key.yyyy),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggtolist2 = select
.GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) })
.ToList(b => new {
b.Key.Title,
b.Key.yyyy,
cou = b.Count(),
sum = b.Sum(b.Key.yyyy),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggsql3 = select
.GroupBy(a => a.Title)
.ToSql(b => new {
b.Key,
cou = b.Count(),
sum = b.Sum(b.Key),
sum2 = b.Sum(b.Value.TypeGuid),
sum3 = b.Sum(b.Value.Type.Parent.Id)
});
} }
[Fact] [Fact]
public void ToAggregate() { public void ToAggregate() {

View File

@ -693,7 +693,54 @@ namespace FreeSql.Tests.PostgreSQL {
arg1 = a.Avg(a.Key.mod4), arg1 = a.Avg(a.Key.mod4),
ccc2 = a.Key.tt2 ?? "now()", ccc2 = a.Key.tt2 ?? "now()",
//ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)")
ccc3 = a.Max(a.Value.Item3.Id)
}); });
var testpid1 = g.pgsql.Insert<TestTypeInfo>().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity();
g.pgsql.Insert<TestInfo>().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows();
var aggsql1 = select
.GroupBy(a => a.Title)
.ToSql(b => new {
b.Key,
cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggtolist1 = select
.GroupBy(a => a.Title)
.ToList(b => new {
b.Key,
cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggsql2 = select
.GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) })
.ToSql(b => new {
b.Key.Title,
b.Key.yyyy,
cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggtolist2 = select
.GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) })
.ToList(b => new {
b.Key.Title,
b.Key.yyyy,
cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggsql3 = select
.GroupBy(a => a.Title)
.ToSql(b => new {
b.Key,
cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid),
sum3 = b.Sum(b.Value.Type.Parent.Id)
});
} }
[Fact] [Fact]
public void ToAggregate() { public void ToAggregate() {

View File

@ -624,7 +624,54 @@ namespace FreeSql.Tests.SqlServer {
arg1 = a.Avg(a.Key.mod4), arg1 = a.Avg(a.Key.mod4),
ccc2 = a.Key.tt2 ?? "now()", ccc2 = a.Key.tt2 ?? "now()",
//ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)")
ccc3 = a.Max(a.Value.Item3.Id)
}); });
var testpid1 = _sqlserverFixture.SqlServer.Insert<TestTypeInfo>().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity();
_sqlserverFixture.SqlServer.Insert<TestInfo>().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows();
var aggsql1 = select
.GroupBy(a => a.Title)
.ToSql(b => new {
b.Key,
cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggtolist1 = select
.GroupBy(a => a.Title)
.ToList(b => new {
b.Key,
cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggsql2 = select
.GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) })
.ToSql(b => new {
b.Key.Title,
b.Key.yyyy,
cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggtolist2 = select
.GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) })
.ToList(b => new {
b.Key.Title,
b.Key.yyyy,
cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggsql3 = select
.GroupBy(a => a.Title)
.ToSql(b => new {
b.Key,
cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid),
sum3 = b.Sum(b.Value.Type.Parent.Id)
});
} }
[Fact] [Fact]
public void ToAggregate() { public void ToAggregate() {

View File

@ -568,7 +568,59 @@ namespace FreeSql.Tests.Sqlite {
arg1 = a.Avg(a.Key.mod4), arg1 = a.Avg(a.Key.mod4),
ccc2 = a.Key.tt2 ?? "now()", ccc2 = a.Key.tt2 ?? "now()",
//ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)")
ccc3 = a.Max(a.Value.Item3.Id)
}); });
var testpid1 = g.sqlite.Insert<TestTypeInfo>().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity();
g.sqlite.Insert<TestInfo>().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows();
var aggsql1 = select
.GroupBy(a => a.Title)
.ToSql(b => new {
b.Key,
cou = b.Count(),
sum = b.Sum(b.Key),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggtolist1 = select
.GroupBy(a => a.Title)
.ToList(b => new {
b.Key,
cou = b.Count(),
sum = b.Sum(b.Key),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggsql2 = select
.GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) })
.ToSql(b => new {
b.Key.Title,
b.Key.yyyy,
cou = b.Count(),
sum = b.Sum(b.Key.yyyy),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggtolist2 = select
.GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) })
.ToList(b => new {
b.Key.Title,
b.Key.yyyy,
cou = b.Count(),
sum = b.Sum(b.Key.yyyy),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggsql3 = select
.GroupBy(a => a.Title)
.ToSql(b => new {
b.Key,
cou = b.Count(),
sum = b.Sum(b.Key),
sum2 = b.Sum(b.Value.TypeGuid),
sum3 = b.Sum(b.Value.Type.Parent.Id)
});
} }
[Fact] [Fact]
public void ToAggregate() { public void ToAggregate() {

View File

@ -53,6 +53,56 @@ namespace FreeSql.Tests {
[Fact] [Fact]
public void Test1() { public void Test1() {
var testpid1 = g.mysql.Insert<TestTypeInfo>().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity();
g.mysql.Insert<TestInfo>().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows();
var aggsql1 = select
.GroupBy(a => a.Title)
.ToSql(b => new {
b.Key,
cou = b.Count(),
sum = b.Sum(b.Key),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggtolist1 = select
.GroupBy(a => a.Title)
.ToList(b => new {
b.Key,
cou = b.Count(),
sum = b.Sum(b.Key),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggsql2 = select
.GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) })
.ToSql(b => new {
b.Key.Title,
b.Key.yyyy,
cou = b.Count(),
sum = b.Sum(b.Key.yyyy),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggtolist2 = select
.GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) })
.ToList(b => new {
b.Key.Title,
b.Key.yyyy,
cou = b.Count(),
sum = b.Sum(b.Key.yyyy),
sum2 = b.Sum(b.Value.TypeGuid)
});
var aggsql3 = select
.GroupBy(a => a.Title)
.ToSql(b => new {
b.Key,
cou = b.Count(),
sum = b.Sum(b.Key),
sum2 = b.Sum(b.Value.TypeGuid),
sum3 = b.Sum(b.Value.Type.Parent.Parent.Id)
});
var sqlrepos = g.sqlite.GetRepository<TestTypeParentInfo, int>(); var sqlrepos = g.sqlite.GetRepository<TestTypeParentInfo, int>();
sqlrepos.Insert(new TestTypeParentInfo { sqlrepos.Insert(new TestTypeParentInfo {
@ -201,7 +251,9 @@ namespace FreeSql.Tests {
.Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0)
.Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100)
.OrderBy(a => a.Key.tt2) .OrderBy(a => a.Key.tt2)
.OrderByDescending(a => a.Count()).ToSql(a => new { a.Key.mod4, a.Key.tt2, max = a.Max("a.id"), max2 = Convert.ToInt64("max(a.id)") }); .OrderByDescending(a => a.Count()).ToSql(a => new {
cou = a.Sum(a.Value.Item1.Id),
a.Key.mod4, a.Key.tt2, max = a.Max("a.id"), max2 = Convert.ToInt64("max(a.id)") });
var groupbysql2 = g.mysql.Select<TestInfo>().From<TestTypeInfo, TestTypeParentInfo>((s, b, c) => s var groupbysql2 = g.mysql.Select<TestInfo>().From<TestTypeInfo, TestTypeParentInfo>((s, b, c) => s
.Where(a => a.Id == 1) .Where(a => a.Id == 1)

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<Version>0.5.4</Version> <Version>0.5.4.1</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description> <Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>

View File

@ -271,7 +271,7 @@ namespace FreeSql {
/// </summary> /// </summary>
/// <param name="key"></param> /// <param name="key"></param>
/// <returns></returns> /// <returns></returns>
ISelectGrouping<TKey> GroupBy<TKey>(Expression<Func<T1, TKey>> exp); ISelectGrouping<TKey, T1> GroupBy<TKey>(Expression<Func<T1, TKey>> exp);
/// <summary> /// <summary>
/// 按列排序OrderBy(a => a.Time) /// 按列排序OrderBy(a => a.Time)

View File

@ -32,7 +32,7 @@ namespace FreeSql {
ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Where(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> exp); ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Where(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> exp);
ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> exp); ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> exp);
ISelectGrouping<TKey> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TKey>> exp); ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TKey>> exp);
ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TMember>> column); ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TMember>> column);
ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TMember>> column); ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TMember>> column);

View File

@ -32,7 +32,7 @@ namespace FreeSql {
ISelect<T1, T2> Where(Expression<Func<T1, T2, bool>> exp); ISelect<T1, T2> Where(Expression<Func<T1, T2, bool>> exp);
ISelect<T1, T2> WhereIf(bool condition, Expression<Func<T1, T2, bool>> exp); ISelect<T1, T2> WhereIf(bool condition, Expression<Func<T1, T2, bool>> exp);
ISelectGrouping<TKey> GroupBy<TKey>(Expression<Func<T1, T2, TKey>> exp); ISelectGrouping<TKey, (T1, T2)> GroupBy<TKey>(Expression<Func<T1, T2, TKey>> exp);
ISelect<T1, T2> OrderBy<TMember>(Expression<Func<T1, T2, TMember>> column); ISelect<T1, T2> OrderBy<TMember>(Expression<Func<T1, T2, TMember>> column);
ISelect<T1, T2> OrderByDescending<TMember>(Expression<Func<T1, T2, TMember>> column); ISelect<T1, T2> OrderByDescending<TMember>(Expression<Func<T1, T2, TMember>> column);

View File

@ -32,7 +32,7 @@ namespace FreeSql {
ISelect<T1, T2, T3> Where(Expression<Func<T1, T2, T3, bool>> exp); ISelect<T1, T2, T3> Where(Expression<Func<T1, T2, T3, bool>> exp);
ISelect<T1, T2, T3> WhereIf(bool condition, Expression<Func<T1, T2, T3, bool>> exp); ISelect<T1, T2, T3> WhereIf(bool condition, Expression<Func<T1, T2, T3, bool>> exp);
ISelectGrouping<TKey> GroupBy<TKey>(Expression<Func<T1, T2, T3, TKey>> exp); ISelectGrouping<TKey, (T1, T2, T3)> GroupBy<TKey>(Expression<Func<T1, T2, T3, TKey>> exp);
ISelect<T1, T2, T3> OrderBy<TMember>(Expression<Func<T1, T2, T3, TMember>> column); ISelect<T1, T2, T3> OrderBy<TMember>(Expression<Func<T1, T2, T3, TMember>> column);
ISelect<T1, T2, T3> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, TMember>> column); ISelect<T1, T2, T3> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, TMember>> column);

View File

@ -32,7 +32,7 @@ namespace FreeSql {
ISelect<T1, T2, T3, T4> Where(Expression<Func<T1, T2, T3, T4, bool>> exp); ISelect<T1, T2, T3, T4> Where(Expression<Func<T1, T2, T3, T4, bool>> exp);
ISelect<T1, T2, T3, T4> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, bool>> exp); ISelect<T1, T2, T3, T4> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, bool>> exp);
ISelectGrouping<TKey> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, TKey>> exp); ISelectGrouping<TKey, (T1, T2, T3, T4)> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, TKey>> exp);
ISelect<T1, T2, T3, T4> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, TMember>> column); ISelect<T1, T2, T3, T4> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, TMember>> column);
ISelect<T1, T2, T3, T4> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, TMember>> column); ISelect<T1, T2, T3, T4> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, TMember>> column);

View File

@ -32,7 +32,7 @@ namespace FreeSql {
ISelect<T1, T2, T3, T4, T5> Where(Expression<Func<T1, T2, T3, T4, T5, bool>> exp); ISelect<T1, T2, T3, T4, T5> Where(Expression<Func<T1, T2, T3, T4, T5, bool>> exp);
ISelect<T1, T2, T3, T4, T5> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, bool>> exp); ISelect<T1, T2, T3, T4, T5> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, bool>> exp);
ISelectGrouping<TKey> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, TKey>> exp); ISelectGrouping<TKey, (T1, T2, T3, T4, T5)> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, TKey>> exp);
ISelect<T1, T2, T3, T4, T5> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, T5, TMember>> column); ISelect<T1, T2, T3, T4, T5> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, T5, TMember>> column);
ISelect<T1, T2, T3, T4, T5> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, T5, TMember>> column); ISelect<T1, T2, T3, T4, T5> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, T5, TMember>> column);

View File

@ -32,7 +32,7 @@ namespace FreeSql {
ISelect<T1, T2, T3, T4, T5, T6> Where(Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp); ISelect<T1, T2, T3, T4, T5, T6> Where(Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp);
ISelect<T1, T2, T3, T4, T5, T6> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp); ISelect<T1, T2, T3, T4, T5, T6> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp);
ISelectGrouping<TKey> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, TKey>> exp); ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6)> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, TKey>> exp);
ISelect<T1, T2, T3, T4, T5, T6> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, TMember>> column); ISelect<T1, T2, T3, T4, T5, T6> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, TMember>> column);
ISelect<T1, T2, T3, T4, T5, T6> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, TMember>> column); ISelect<T1, T2, T3, T4, T5, T6> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, TMember>> column);

View File

@ -32,7 +32,7 @@ namespace FreeSql {
ISelect<T1, T2, T3, T4, T5, T6, T7> Where(Expression<Func<T1, T2, T3, T4, T5, T6, T7, bool>> exp); ISelect<T1, T2, T3, T4, T5, T6, T7> Where(Expression<Func<T1, T2, T3, T4, T5, T6, T7, bool>> exp);
ISelect<T1, T2, T3, T4, T5, T6, T7> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, T7, bool>> exp); ISelect<T1, T2, T3, T4, T5, T6, T7> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, T7, bool>> exp);
ISelectGrouping<TKey> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TKey>> exp); ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6, T7)> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TKey>> exp);
ISelect<T1, T2, T3, T4, T5, T6, T7> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TMember>> column); ISelect<T1, T2, T3, T4, T5, T6, T7> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TMember>> column);
ISelect<T1, T2, T3, T4, T5, T6, T7> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TMember>> column); ISelect<T1, T2, T3, T4, T5, T6, T7> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TMember>> column);

View File

@ -32,7 +32,7 @@ namespace FreeSql {
ISelect<T1, T2, T3, T4, T5, T6, T7, T8> Where(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, bool>> exp); ISelect<T1, T2, T3, T4, T5, T6, T7, T8> Where(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, bool>> exp);
ISelect<T1, T2, T3, T4, T5, T6, T7, T8> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, bool>> exp); ISelect<T1, T2, T3, T4, T5, T6, T7, T8> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, bool>> exp);
ISelectGrouping<TKey> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TKey>> exp); ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6, T7, T8)> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TKey>> exp);
ISelect<T1, T2, T3, T4, T5, T6, T7, T8> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TMember>> column); ISelect<T1, T2, T3, T4, T5, T6, T7, T8> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TMember>> column);
ISelect<T1, T2, T3, T4, T5, T6, T7, T8> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TMember>> column); ISelect<T1, T2, T3, T4, T5, T6, T7, T8> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TMember>> column);

View File

@ -32,7 +32,7 @@ namespace FreeSql {
ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> Where(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, bool>> exp); ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> Where(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, bool>> exp);
ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, bool>> exp); ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> WhereIf(bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, bool>> exp);
ISelectGrouping<TKey> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TKey>> exp); ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9)> GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TKey>> exp);
ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TMember>> column); ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> OrderBy<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TMember>> column);
ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TMember>> column); ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> OrderByDescending<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TMember>> column);

View File

@ -5,13 +5,13 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FreeSql { namespace FreeSql {
public interface ISelectGrouping<T1> { public interface ISelectGrouping<TKey, TValue> {
/// <summary> /// <summary>
/// 按聚合条件过滤Where(a => a.Count() > 10) /// 按聚合条件过滤Where(a => a.Count() > 10)
/// </summary> /// </summary>
/// <param name="exp">lambda表达式</param> /// <param name="exp">lambda表达式</param>
/// <returns></returns> /// <returns></returns>
ISelectGrouping<T1> Having(Expression<Func<ISelectGroupingAggregate<T1>, bool>> exp); ISelectGrouping<TKey, TValue> Having(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, bool>> exp);
/// <summary> /// <summary>
/// 按列排序OrderBy(a => a.Time) /// 按列排序OrderBy(a => a.Time)
@ -19,13 +19,13 @@ namespace FreeSql {
/// <typeparam name="TMember"></typeparam> /// <typeparam name="TMember"></typeparam>
/// <param name="column"></param> /// <param name="column"></param>
/// <returns></returns> /// <returns></returns>
ISelectGrouping<T1> OrderBy<TMember>(Expression<Func<ISelectGroupingAggregate<T1>, TMember>> column); ISelectGrouping<TKey, TValue> OrderBy<TMember>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TMember>> column);
/// <summary> /// <summary>
/// 按列倒向排序OrderByDescending(a => a.Time) /// 按列倒向排序OrderByDescending(a => a.Time)
/// </summary> /// </summary>
/// <param name="column">列</param> /// <param name="column">列</param>
/// <returns></returns> /// <returns></returns>
ISelectGrouping<T1> OrderByDescending<TMember>(Expression<Func<ISelectGroupingAggregate<T1>, TMember>> column); ISelectGrouping<TKey, TValue> OrderByDescending<TMember>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TMember>> column);
/// <summary> /// <summary>
/// 执行SQL查询返回指定字段的记录记录不存在时返回 Count 为 0 的列表 /// 执行SQL查询返回指定字段的记录记录不存在时返回 Count 为 0 的列表
@ -33,8 +33,8 @@ namespace FreeSql {
/// <typeparam name="TReturn">返回类型</typeparam> /// <typeparam name="TReturn">返回类型</typeparam>
/// <param name="select">选择列</param> /// <param name="select">选择列</param>
/// <returns></returns> /// <returns></returns>
List<TReturn> ToList<TReturn>(Expression<Func<ISelectGroupingAggregate<T1>, TReturn>> select); List<TReturn> ToList<TReturn>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TReturn>> select);
Task<List<TReturn>> ToListAsync<TReturn>(Expression<Func<ISelectGroupingAggregate<T1>, TReturn>> select); Task<List<TReturn>> ToListAsync<TReturn>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TReturn>> select);
/// <summary> /// <summary>
/// 返回即将执行的SQL语句 /// 返回即将执行的SQL语句
@ -42,7 +42,7 @@ namespace FreeSql {
/// <typeparam name="TReturn">返回类型</typeparam> /// <typeparam name="TReturn">返回类型</typeparam>
/// <param name="select">选择列</param> /// <param name="select">选择列</param>
/// <returns></returns> /// <returns></returns>
string ToSql<TReturn>(Expression<Func<ISelectGroupingAggregate<T1>, TReturn>> select); string ToSql<TReturn>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TReturn>> select);
/// <summary> /// <summary>
@ -50,25 +50,25 @@ namespace FreeSql {
/// </summary> /// </summary>
/// <param name="offset"></param> /// <param name="offset"></param>
/// <returns></returns> /// <returns></returns>
ISelectGrouping<T1> Skip(int offset); ISelectGrouping<TKey, TValue> Skip(int offset);
/// <summary> /// <summary>
/// 查询向后偏移行数 /// 查询向后偏移行数
/// </summary> /// </summary>
/// <param name="offset">行数</param> /// <param name="offset">行数</param>
/// <returns></returns> /// <returns></returns>
ISelectGrouping<T1> Offset(int offset); ISelectGrouping<TKey, TValue> Offset(int offset);
/// <summary> /// <summary>
/// 查询多少条数据 /// 查询多少条数据
/// </summary> /// </summary>
/// <param name="limit"></param> /// <param name="limit"></param>
/// <returns></returns> /// <returns></returns>
ISelectGrouping<T1> Limit(int limit); ISelectGrouping<TKey, TValue> Limit(int limit);
/// <summary> /// <summary>
/// 查询多少条数据 /// 查询多少条数据
/// </summary> /// </summary>
/// <param name="limit"></param> /// <param name="limit"></param>
/// <returns></returns> /// <returns></returns>
ISelectGrouping<T1> Take(int limit); ISelectGrouping<TKey, TValue> Take(int limit);
/// <summary> /// <summary>
/// 分页 /// 分页
@ -76,14 +76,14 @@ namespace FreeSql {
/// <param name="pageIndex">第几页</param> /// <param name="pageIndex">第几页</param>
/// <param name="pageSize">每页多少</param> /// <param name="pageSize">每页多少</param>
/// <returns></returns> /// <returns></returns>
ISelectGrouping<T1> Page(int pageIndex, int pageSize); ISelectGrouping<TKey, TValue> Page(int pageIndex, int pageSize);
} }
public interface ISelectGroupingAggregate<T1> { public interface ISelectGroupingAggregate<TKey> {
/// <summary> /// <summary>
/// 分组的数据 /// 分组的数据
/// </summary> /// </summary>
T1 Key { get; set; } TKey Key { get; set; }
/// <summary> /// <summary>
/// 记录总数 /// 记录总数
/// </summary> /// </summary>
@ -117,4 +117,10 @@ namespace FreeSql {
/// <returns></returns> /// <returns></returns>
T3 Min<T3>(T3 column); T3 Min<T3>(T3 column);
} }
public interface ISelectGroupingAggregate<TKey, TValue> : ISelectGroupingAggregate<TKey> {
/// <summary>
/// 所有元素
/// </summary>
TValue Value { get; set; }
}
} }

View File

@ -726,7 +726,7 @@ namespace FreeSql.Internal {
case ExpressionType.MemberAccess: case ExpressionType.MemberAccess:
var exp2Type = exp2.Type; var exp2Type = exp2.Type;
if (exp2Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) exp2Type = exp2Type.GenericTypeArguments.FirstOrDefault() ?? exp2.Type; if (exp2Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) exp2Type = exp2Type.GenericTypeArguments.LastOrDefault() ?? exp2.Type;
var tb2tmp = _common.GetTableByEntity(exp2Type); var tb2tmp = _common.GetTableByEntity(exp2Type);
var mp2 = exp2 as MemberExpression; var mp2 = exp2 as MemberExpression;
if (mp2?.Member.Name == "Key" && mp2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) continue; if (mp2?.Member.Name == "Key" && mp2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) continue;
@ -794,7 +794,7 @@ namespace FreeSql.Internal {
left = tmp; left = tmp;
} }
if (right == "NULL") tryoper = tryoper == "=" ? " IS " : " IS NOT "; if (right == "NULL") tryoper = tryoper == "=" ? " IS " : " IS NOT ";
if (tryoper == "+" && (expBinary.Left.Type.FullName == "System.String" || expBinary.Right.Type.FullName == "System.String")) return _common.StringConcat(left, right, expBinary.Left.Type, expBinary.Right.Type); if (tryoper == "+" && (expBinary.Left.Type.FullName == "System.String" || expBinary.Right.Type.FullName == "System.String")) return _common.StringConcat(new[] { left, right }, new[] { expBinary.Left.Type, expBinary.Right.Type });
if (tryoper == "%") return _common.Mod(left, right, expBinary.Left.Type, expBinary.Right.Type); if (tryoper == "%") return _common.Mod(left, right, expBinary.Left.Type, expBinary.Right.Type);
if (_common._orm.Ado.DataType == DataType.MySql) { if (_common._orm.Ado.DataType == DataType.MySql) {
//处理c#变态enum convert a.EnumType1 == Xxx.Xxx被转成了 Convert(a.EnumType1, Int32) == 1 //处理c#变态enum convert a.EnumType1 == Xxx.Xxx被转成了 Convert(a.EnumType1, Int32) == 1

View File

@ -679,14 +679,14 @@ namespace FreeSql.Internal.CommonProvider {
protected TMember InternalSum<TMember>(Expression exp) => this.ToList<TMember>($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault(); protected TMember InternalSum<TMember>(Expression exp) => this.ToList<TMember>($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault();
async protected Task<TMember> InternalSumAsync<TMember>(Expression exp) => (await this.ToListAsync<TMember>($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault(); async protected Task<TMember> InternalSumAsync<TMember>(Expression exp) => (await this.ToListAsync<TMember>($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault();
protected ISelectGrouping<TKey> InternalGroupBy<TKey>(Expression columns) { protected ISelectGrouping<TKey, TValue> InternalGroupBy<TKey, TValue>(Expression columns) {
var map = new ReadAnonymousTypeInfo(); var map = new ReadAnonymousTypeInfo();
var field = new StringBuilder(); var field = new StringBuilder();
var index = -10000; //临时规则,不返回 as1 var index = -10000; //临时规则,不返回 as1
_commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null); _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null);
this.GroupBy(field.Length > 0 ? field.Remove(0, 2).ToString() : null); this.GroupBy(field.Length > 0 ? field.Remove(0, 2).ToString() : null);
return new SelectGroupingProvider<TKey>(this, map, _commonExpression); return new SelectGroupingProvider<TKey, TValue>(this, map, _commonExpression, _tables);
} }
protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) { protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) {
_commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null); _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null);

View File

@ -44,10 +44,10 @@ namespace FreeSql.Internal.CommonProvider {
return this.InternalAvgAsync<TMember>(column?.Body); return this.InternalAvgAsync<TMember>(column?.Body);
} }
ISelectGrouping<TKey> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TKey>> exp) { ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TKey>> exp) {
if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body); if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)>(exp?.Body);
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
return this.InternalGroupBy<TKey>(exp?.Body); return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> (exp?.Body);
} }
TMember ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TMember>> column) { TMember ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TMember>> column) {

View File

@ -87,10 +87,10 @@ namespace FreeSql.Internal.CommonProvider {
public abstract ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class;// { this.InternalFrom(exp?.Body); var ret = new Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); Select0Provider<ISelect<T1>, T1>.CopyData(this, ret, exp?.Parameters); return ret; } public abstract ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class;// { this.InternalFrom(exp?.Body); var ret = new Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); Select0Provider<ISelect<T1>, T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public ISelectGrouping<TKey> GroupBy<TKey>(Expression<Func<T1, TKey>> columns) { public ISelectGrouping<TKey, T1> GroupBy<TKey>(Expression<Func<T1, TKey>> columns) {
if (columns == null) return this.InternalGroupBy<TKey>(columns); if (columns == null) return this.InternalGroupBy<TKey, T1>(columns);
_tables[0].Parameter = columns.Parameters[0]; _tables[0].Parameter = columns.Parameters[0];
return this.InternalGroupBy<TKey>(columns); return this.InternalGroupBy<TKey, T1>(columns);
} }
public TMember Max<TMember>(Expression<Func<T1, TMember>> column) { public TMember Max<TMember>(Expression<Func<T1, TMember>> column) {

View File

@ -28,10 +28,10 @@ namespace FreeSql.Internal.CommonProvider {
return this.InternalAvgAsync<TMember>(column?.Body); return this.InternalAvgAsync<TMember>(column?.Body);
} }
ISelectGrouping<TKey> ISelect<T1, T2>.GroupBy<TKey>(Expression<Func<T1, T2, TKey>> exp) { ISelectGrouping<TKey, (T1, T2)> ISelect<T1, T2>.GroupBy<TKey>(Expression<Func<T1, T2, TKey>> exp) {
if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body); if (exp == null) return this.InternalGroupBy<TKey, (T1, T2)>(exp?.Body);
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
return this.InternalGroupBy<TKey>(exp?.Body); return this.InternalGroupBy<TKey, (T1, T2)>(exp?.Body);
} }
TMember ISelect<T1, T2>.Max<TMember>(Expression<Func<T1, T2, TMember>> column) { TMember ISelect<T1, T2>.Max<TMember>(Expression<Func<T1, T2, TMember>> column) {

View File

@ -30,10 +30,10 @@ namespace FreeSql.Internal.CommonProvider {
return this.InternalAvgAsync<TMember>(column?.Body); return this.InternalAvgAsync<TMember>(column?.Body);
} }
ISelectGrouping<TKey> ISelect<T1, T2, T3>.GroupBy<TKey>(Expression<Func<T1, T2, T3, TKey>> exp) { ISelectGrouping<TKey, (T1, T2, T3)> ISelect<T1, T2, T3>.GroupBy<TKey>(Expression<Func<T1, T2, T3, TKey>> exp) {
if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body); if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3)>(exp?.Body);
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
return this.InternalGroupBy<TKey>(exp?.Body); return this.InternalGroupBy<TKey, (T1, T2, T3)>(exp?.Body);
} }
TMember ISelect<T1, T2, T3>.Max<TMember>(Expression<Func<T1, T2, T3, TMember>> column) { TMember ISelect<T1, T2, T3>.Max<TMember>(Expression<Func<T1, T2, T3, TMember>> column) {

View File

@ -32,10 +32,10 @@ namespace FreeSql.Internal.CommonProvider {
return this.InternalAvgAsync<TMember>(column?.Body); return this.InternalAvgAsync<TMember>(column?.Body);
} }
ISelectGrouping<TKey> ISelect<T1, T2, T3, T4>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, TKey>> exp) { ISelectGrouping<TKey, (T1, T2, T3, T4)> ISelect<T1, T2, T3, T4>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, TKey>> exp) {
if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body); if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4)>(exp?.Body);
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
return this.InternalGroupBy<TKey>(exp?.Body); return this.InternalGroupBy<TKey, (T1, T2, T3, T4)>(exp?.Body);
} }
TMember ISelect<T1, T2, T3, T4>.Max<TMember>(Expression<Func<T1, T2, T3, T4, TMember>> column) { TMember ISelect<T1, T2, T3, T4>.Max<TMember>(Expression<Func<T1, T2, T3, T4, TMember>> column) {

View File

@ -34,10 +34,10 @@ namespace FreeSql.Internal.CommonProvider {
return this.InternalAvgAsync<TMember>(column?.Body); return this.InternalAvgAsync<TMember>(column?.Body);
} }
ISelectGrouping<TKey> ISelect<T1, T2, T3, T4, T5>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, TKey>> exp) { ISelectGrouping<TKey, (T1, T2, T3, T4, T5)> ISelect<T1, T2, T3, T4, T5>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, TKey>> exp) {
if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body); if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5)>(exp?.Body);
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
return this.InternalGroupBy<TKey>(exp?.Body); return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5)>(exp?.Body);
} }
TMember ISelect<T1, T2, T3, T4, T5>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, TMember>> column) { TMember ISelect<T1, T2, T3, T4, T5>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, TMember>> column) {

View File

@ -36,10 +36,10 @@ namespace FreeSql.Internal.CommonProvider {
return this.InternalAvgAsync<TMember>(column?.Body); return this.InternalAvgAsync<TMember>(column?.Body);
} }
ISelectGrouping<TKey> ISelect<T1, T2, T3, T4, T5, T6>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, TKey>> exp) { ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6)> ISelect<T1, T2, T3, T4, T5, T6>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, TKey>> exp) {
if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body); if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6)>(exp?.Body);
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
return this.InternalGroupBy<TKey>(exp?.Body); return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6)>(exp?.Body);
} }
TMember ISelect<T1, T2, T3, T4, T5, T6>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, TMember>> column) { TMember ISelect<T1, T2, T3, T4, T5, T6>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, TMember>> column) {

View File

@ -38,10 +38,10 @@ namespace FreeSql.Internal.CommonProvider {
return this.InternalAvgAsync<TMember>(column?.Body); return this.InternalAvgAsync<TMember>(column?.Body);
} }
ISelectGrouping<TKey> ISelect<T1, T2, T3, T4, T5, T6, T7>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TKey>> exp) { ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6, T7)> ISelect<T1, T2, T3, T4, T5, T6, T7>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TKey>> exp) {
if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body); if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7)>(exp?.Body);
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
return this.InternalGroupBy<TKey>(exp?.Body); return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7)>(exp?.Body);
} }
TMember ISelect<T1, T2, T3, T4, T5, T6, T7>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TMember>> column) { TMember ISelect<T1, T2, T3, T4, T5, T6, T7>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TMember>> column) {

View File

@ -40,10 +40,10 @@ namespace FreeSql.Internal.CommonProvider {
return this.InternalAvgAsync<TMember>(column?.Body); return this.InternalAvgAsync<TMember>(column?.Body);
} }
ISelectGrouping<TKey> ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TKey>> exp) { ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6, T7, T8)> ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TKey>> exp) {
if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body); if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7, T8)>(exp?.Body);
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
return this.InternalGroupBy<TKey>(exp?.Body); return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7, T8)>(exp?.Body);
} }
TMember ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TMember>> column) { TMember ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TMember>> column) {

View File

@ -42,10 +42,10 @@ namespace FreeSql.Internal.CommonProvider {
return this.InternalAvgAsync<TMember>(column?.Body); return this.InternalAvgAsync<TMember>(column?.Body);
} }
ISelectGrouping<TKey> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TKey>> exp) { ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9)> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TKey>> exp) {
if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body); if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9)>(exp?.Body);
for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
return this.InternalGroupBy<TKey>(exp?.Body); return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9)>(exp?.Body);
} }
TMember ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TMember>> column) { TMember ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TMember>> column) {

View File

@ -8,48 +8,89 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FreeSql.Internal.CommonProvider { namespace FreeSql.Internal.CommonProvider {
class SelectGroupingProvider<T1> : ISelectGrouping<T1> { class SelectGroupingProvider<TKey, TValue> : ISelectGrouping<TKey, TValue> {
internal object _select; internal object _select;
internal ReadAnonymousTypeInfo _map; internal ReadAnonymousTypeInfo _map;
internal CommonExpression _comonExp; internal CommonExpression _comonExp;
public SelectGroupingProvider(object select, ReadAnonymousTypeInfo map, CommonExpression comonExp) { internal List<SelectTableInfo> _tables;
public SelectGroupingProvider(object select, ReadAnonymousTypeInfo map, CommonExpression comonExp, List<SelectTableInfo> tables) {
_select = select; _select = select;
_map = map; _map = map;
_comonExp = comonExp; _comonExp = comonExp;
_tables = tables;
} }
string getSelectGroupingMapString(Expression[] members) { string getSelectGroupingMapString(Expression[] members) {
var read = _map; if (members.Any() == false) return _map.DbField;
for (var a = 0; a < members.Length; a++) { var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name;
read = read.Childs.Where(z => z.CsName == (members[a] as MemberExpression)?.Member.Name).FirstOrDefault(); switch(parentName) {
if (read == null) return null; case "Key":
var read = _map;
for (var a = 0; a < members.Length; a++) {
read = read.Childs.Where(z => z.CsName == (members[a] as MemberExpression)?.Member.Name).FirstOrDefault();
if (read == null) return null;
}
return read.DbField;
case "Value":
var tb = _tables.First();
var foridx = 0;
if (members.Length > 1) {
var mem0 = (members.FirstOrDefault() as MemberExpression);
var mem0Name = mem0?.Member.Name;
if (mem0Name?.StartsWith("Item") == true && int.TryParse(mem0Name.Substring(4), out var tryitemidx)) {
if (tryitemidx == 1) foridx++;
else {
var alias = $"SP10{(char)(96 + tryitemidx)}";
var tmptb = _tables.Where(a => a.AliasInit == alias && a.Table.Type == mem0.Type).FirstOrDefault();
if (tmptb != null) {
tb = tmptb;
foridx++;
}
}
}
}
var parmExp = Expression.Parameter(tb.Table.Type, tb.Alias);
Expression retExp = parmExp;
for (var a = foridx; a < members.Length; a++) {
switch(members[a].NodeType) {
case ExpressionType.Call:
retExp = Expression.Call(retExp, (members[a] as MethodCallExpression).Method);
break;
case ExpressionType.MemberAccess:
retExp = Expression.MakeMemberAccess(retExp, (members[a] as MemberExpression).Member);
break;
default:
return null;
}
}
return _comonExp.ExpressionLambdaToSql(retExp, _tables, null, null, SelectTableInfoType.From, true, true, CommonExpression.ExpressionStyle.Where);
} }
return read.DbField; return null;
} }
public ISelectGrouping<T1> Having(Expression<Func<ISelectGroupingAggregate<T1>, bool>> exp) { public ISelectGrouping<TKey, TValue> Having(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, bool>> exp) {
var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString); var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString);
var method = _select.GetType().GetMethod("Having", new[] { typeof(string), typeof(object) }); var method = _select.GetType().GetMethod("Having", new[] { typeof(string), typeof(object) });
method.Invoke(_select, new object[] { sql, null }); method.Invoke(_select, new object[] { sql, null });
return this; return this;
} }
public ISelectGrouping<T1> OrderBy<TMember>(Expression<Func<ISelectGroupingAggregate<T1>, TMember>> column) { public ISelectGrouping<TKey, TValue> OrderBy<TMember>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TMember>> column) {
var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString); var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString);
var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) });
method.Invoke(_select, new object[] { sql, null }); method.Invoke(_select, new object[] { sql, null });
return this; return this;
} }
public ISelectGrouping<T1> OrderByDescending<TMember>(Expression<Func<ISelectGroupingAggregate<T1>, TMember>> column) { public ISelectGrouping<TKey, TValue> OrderByDescending<TMember>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TMember>> column) {
var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString); var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString);
var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) });
method.Invoke(_select, new object[] { $"{sql} DESC", null }); method.Invoke(_select, new object[] { $"{sql} DESC", null });
return this; return this;
} }
public List<TReturn> ToList<TReturn>(Expression<Func<ISelectGroupingAggregate<T1>, TReturn>> select) { public List<TReturn> ToList<TReturn>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TReturn>> select) {
var map = new ReadAnonymousTypeInfo(); var map = new ReadAnonymousTypeInfo();
var field = new StringBuilder(); var field = new StringBuilder();
var index = 0; var index = 0;
@ -59,7 +100,7 @@ namespace FreeSql.Internal.CommonProvider {
method = method.MakeGenericMethod(typeof(TReturn)); method = method.MakeGenericMethod(typeof(TReturn));
return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List<TReturn>; return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List<TReturn>;
} }
public Task<List<TReturn>> ToListAsync<TReturn>(Expression<Func<ISelectGroupingAggregate<T1>, TReturn>> select) { public Task<List<TReturn>> ToListAsync<TReturn>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TReturn>> select) {
var map = new ReadAnonymousTypeInfo(); var map = new ReadAnonymousTypeInfo();
var field = new StringBuilder(); var field = new StringBuilder();
var index = 0; var index = 0;
@ -70,7 +111,7 @@ namespace FreeSql.Internal.CommonProvider {
return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task<List<TReturn>>; return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task<List<TReturn>>;
} }
public string ToSql<TReturn>(Expression<Func<ISelectGroupingAggregate<T1>, TReturn>> select) { public string ToSql<TReturn>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TReturn>> select) {
var map = new ReadAnonymousTypeInfo(); var map = new ReadAnonymousTypeInfo();
var field = new StringBuilder(); var field = new StringBuilder();
var index = 0; var index = 0;
@ -80,21 +121,21 @@ namespace FreeSql.Internal.CommonProvider {
return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string; return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string;
} }
public ISelectGrouping<T1> Skip(int offset) { public ISelectGrouping<TKey, TValue> Skip(int offset) {
var method = _select.GetType().GetMethod("Skip", new[] { typeof(int) }); var method = _select.GetType().GetMethod("Skip", new[] { typeof(int) });
method.Invoke(_select, new object[] { offset }); method.Invoke(_select, new object[] { offset });
return this; return this;
} }
public ISelectGrouping<T1> Offset(int offset) => this.Skip(offset); public ISelectGrouping<TKey, TValue> Offset(int offset) => this.Skip(offset);
public ISelectGrouping<T1> Limit(int limit) { public ISelectGrouping<TKey, TValue> Limit(int limit) {
var method = _select.GetType().GetMethod("Limit", new[] { typeof(int) }); var method = _select.GetType().GetMethod("Limit", new[] { typeof(int) });
method.Invoke(_select, new object[] { limit }); method.Invoke(_select, new object[] { limit });
return this; return this;
} }
public ISelectGrouping<T1> Take(int limit) => this.Limit(limit); public ISelectGrouping<TKey, TValue> Take(int limit) => this.Limit(limit);
public ISelectGrouping<T1> Page(int pageIndex, int pageSize) { public ISelectGrouping<TKey, TValue> Page(int pageIndex, int pageSize) {
var method = _select.GetType().GetMethod("Page", new[] { typeof(int), typeof(int) }); var method = _select.GetType().GetMethod("Page", new[] { typeof(int), typeof(int) });
method.Invoke(_select, new object[] { pageIndex, pageSize }); method.Invoke(_select, new object[] { pageIndex, pageSize });
return this; return this;

View File

@ -21,7 +21,7 @@ namespace FreeSql.Internal {
internal abstract string QuoteSqlName(string name); internal abstract string QuoteSqlName(string name);
internal abstract string QuoteParamterName(string name); internal abstract string QuoteParamterName(string name);
internal abstract string IsNull(string sql, object value); internal abstract string IsNull(string sql, object value);
internal abstract string StringConcat(string left, string right, Type leftType, Type rightType); internal abstract string StringConcat(string[] objs, Type[] types);
internal abstract string Mod(string left, string right, Type leftType, Type rightType); internal abstract string Mod(string left, string right, Type leftType, Type rightType);
internal abstract string QuoteWriteParamter(Type type, string paramterName); internal abstract string QuoteWriteParamter(Type type, string paramterName);
internal abstract string QuoteReadColumn(Type type, string columnName); internal abstract string QuoteReadColumn(Type type, string columnName);

View File

@ -3,7 +3,16 @@
namespace FreeSql.Internal.Model { namespace FreeSql.Internal.Model {
class SelectTableInfo { class SelectTableInfo {
public TableInfo Table { get; set; } public TableInfo Table { get; set; }
public string Alias { get; set; }
private string _alias;
public string Alias {
get => _alias;
set {
_alias = value;
if (string.IsNullOrEmpty(AliasInit)) AliasInit = value;
}
}
public string AliasInit { get; set; }
public string On { get; set; } public string On { get; set; }
public string NavigateCondition { get; set; } public string NavigateCondition { get; set; }
public ParameterExpression Parameter { get; set; } public ParameterExpression Parameter { get; set; }

View File

@ -208,6 +208,8 @@ namespace FreeSql.MySql {
case "IsNullOrEmpty": case "IsNullOrEmpty":
var arg1 = getExp(exp.Arguments[0]); var arg1 = getExp(exp.Arguments[0]);
return $"({arg1} is null or {arg1} = '')"; return $"({arg1} is null or {arg1} = '')";
case "Concat":
return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null);
} }
} else { } else {
var left = getExp(exp.Object); var left = getExp(exp.Object);
@ -335,7 +337,7 @@ namespace FreeSql.MySql {
} }
break; break;
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
case "CompareTo": return $"timestampdiff(microsecond,{getExp(exp.Arguments[0])},{left})"; case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})";
case "ToString": return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')"; case "ToString": return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')";
} }
} }

View File

@ -4,6 +4,7 @@ using MySql.Data.MySqlClient;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Linq;
using System.Text; using System.Text;
namespace FreeSql.MySql { namespace FreeSql.MySql {
@ -50,7 +51,7 @@ namespace FreeSql.MySql {
} }
internal override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; internal override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
internal override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; internal override string IsNull(string sql, object value) => $"ifnull({sql}, {value})";
internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"concat({left}, {right})"; internal override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})";
internal override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; internal override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}";
internal override string QuoteWriteParamter(Type type, string paramterName) { internal override string QuoteWriteParamter(Type type, string paramterName) {
switch (type.FullName) { switch (type.FullName) {

View File

@ -208,6 +208,8 @@ namespace FreeSql.Oracle {
case "IsNullOrEmpty": case "IsNullOrEmpty":
var arg1 = getExp(exp.Arguments[0]); var arg1 = getExp(exp.Arguments[0]);
return $"({arg1} is null or {arg1} = '')"; return $"({arg1} is null or {arg1} = '')";
case "Concat":
return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null);
} }
} else { } else {
var left = getExp(exp.Object); var left = getExp(exp.Object);

View File

@ -46,7 +46,7 @@ namespace FreeSql.Oracle {
} }
internal override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; internal override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
internal override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; internal override string IsNull(string sql, object value) => $"nvl({sql}, {value})";
internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"{left} || {right}"; internal override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}";
internal override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; internal override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})";
internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName; internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;

View File

@ -303,6 +303,8 @@ namespace FreeSql.PostgreSQL {
case "IsNullOrEmpty": case "IsNullOrEmpty":
var arg1 = getExp(exp.Arguments[0]); var arg1 = getExp(exp.Arguments[0]);
return $"({arg1} is null or {arg1} = '')"; return $"({arg1} is null or {arg1} = '')";
case "Concat":
return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null);
} }
} else { } else {
var left = getExp(exp.Object); var left = getExp(exp.Object);

View File

@ -105,7 +105,7 @@ namespace FreeSql.PostgreSQL {
} }
internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
internal override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; internal override string IsNull(string sql, object value) => $"coalesce({sql}, {value})";
internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"{left} || {right}"; internal override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}";
internal override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; internal override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}";
internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName; internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;

View File

@ -211,6 +211,8 @@ namespace FreeSql.SqlServer {
case "IsNullOrEmpty": case "IsNullOrEmpty":
var arg1 = getExp(exp.Arguments[0]); var arg1 = getExp(exp.Arguments[0]);
return $"({arg1} is null or {arg1} = '')"; return $"({arg1} is null or {arg1} = '')";
case "Concat":
return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray());
} }
} else { } else {
var left = getExp(exp.Object); var left = getExp(exp.Object);

View File

@ -43,7 +43,13 @@ namespace FreeSql.SqlServer {
} }
internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
internal override string IsNull(string sql, object value) => $"isnull({sql}, {value})"; internal override string IsNull(string sql, object value) => $"isnull({sql}, {value})";
internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"{(leftType.FullName == "System.String" ? left : $"cast({left} as nvarchar)")} + {(rightType.FullName == "System.String" ? right : $"cast({right} as nvarchar)")}"; internal override string StringConcat(string[] objs, Type[] types) {
var sb = new StringBuilder();
var news = new string[objs.Length];
for (var a = 0; a < objs.Length; a++)
news[a] = types[a] == typeof(string) ? objs[a] : $"cast({objs[a]} as nvarchar)";
return string.Join(" + ", news);
}
internal override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; internal override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}";
internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName; internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;

View File

@ -208,6 +208,8 @@ namespace FreeSql.Sqlite {
case "IsNullOrEmpty": case "IsNullOrEmpty":
var arg1 = getExp(exp.Arguments[0]); var arg1 = getExp(exp.Arguments[0]);
return $"({arg1} is null or {arg1} = '')"; return $"({arg1} is null or {arg1} = '')";
case "Concat":
return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null);
} }
} else { } else {
var left = getExp(exp.Object); var left = getExp(exp.Object);

View File

@ -61,7 +61,7 @@ namespace FreeSql.Sqlite {
} }
internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
internal override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; internal override string IsNull(string sql, object value) => $"ifnull({sql}, {value})";
internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"{left} || {right}"; internal override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}";
internal override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; internal override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}";
internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName; internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;