mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
in/not in
This commit is contained in:
parent
43080a4052
commit
96a944c534
@ -1,21 +1,54 @@
|
|||||||
# 表达式函数
|
# 表达式函数
|
||||||
| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 |
|
| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 |
|
||||||
| - | - | - | - | - |
|
| - | - | - | - | - |
|
||||||
| a ? b : c | case when a then b else c end | case when a then b else c end | - | a成立时取b值,否则取c值 |
|
| a ? b : c | case when athen b else c end | case when athen b else c end | case when athen b else c end | a成立时取b值,否则取c值 |
|
||||||
| a ?? b | ifnull(a, b) | isnull(a, b) | coalesce(a, b) | 当a为null时,取b值 |
|
| a ?? b | ifnull(a, b) | isnull(a, b) | coalesce(a, b) | 当a为null时,取b值 |
|
||||||
| 数字 + 数字 | a + b | a + b | a + b | 数字相加 |
|
| 数字 + 数字 | a + b | a + b | a + b | 数字相加 |
|
||||||
| 数字 + 字符串 | concat(a, b) | cast(a as varchar) + cast(b as varchar) | case(a as varchar) \|\| b | 字符串相加,a或b任意一个为字符串时 |
|
| 数字 + 字符串 | concat(a, b) | cast(a as varchar) + cast(b as varchar) | case(a as varchar)\|\| b | 字符串相加,a或b任意一个为字符串时 |
|
||||||
| a - b | a - b | a - b | a - b | 减
|
| a - b | a - b | a - b | a - b | 减
|
||||||
| a * b | a * b | a * b | a * b | 乘
|
| a * b | a * b | a * b | a * b | 乘
|
||||||
| a / b | a / b | a / b | a / b | 乘
|
| a / b | a / b | a / b | a / b | 乘
|
||||||
| a % b | a mod b | a mod b | a mod b | 模
|
| a % b | a % b | a % b | a % b | 模
|
||||||
|
|
||||||
> 等等...
|
> 等等...
|
||||||
|
|
||||||
|
### 数组
|
||||||
|
| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 |
|
||||||
|
| - | - | - | - | - |
|
||||||
|
| a.Length | - | - | case when a is null then 0 else array_length(a,1) end | 数组长度 |
|
||||||
|
| 常量数组.Length | - | - | array_length(array[常量数组元素逗号分割],1) | 数组长度 |
|
||||||
|
| a.Any() | - | - | case when a is null then 0 else array_length(a,1) end > 0 | 数组是否为空 |
|
||||||
|
| 常量数组.Contains(b) | b in (常量数组元素逗号分割) | b in (常量数组元素逗号分割) | b in (常量数组元素逗号分割) | IN查询 |
|
||||||
|
| a.Contains(b) | - | - | a @> array[b] | a数组是否包含b元素 |
|
||||||
|
| a.Concat(b) | - | - | a \|\| b | 数组相连 |
|
||||||
|
| a.Count() | - | - | 同 Length | 数组长度 |
|
||||||
|
|
||||||
|
### 字典 Dictionary<string, string>
|
||||||
|
| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 |
|
||||||
|
| - | - | - | - | - |
|
||||||
|
| a.Count | - | - | case when a is null then 0 else array_length(akeys(a),1) end | 字典长度 |
|
||||||
|
| a.Keys | - | - | akeys(a) | 返回字典所有key数组 |
|
||||||
|
| a.Values | - | - | avals(a) | 返回字典所有value数组 |
|
||||||
|
| a.Contains(b) | - | - | a @> b | 字典是否包含b
|
||||||
|
| a.ContainsKey(b) | - | - | a? b | 字典是否包含key
|
||||||
|
| a.Concat(b) | - | - | a \|\| b | 字典相连 |
|
||||||
|
| a.Count() | - | - | 同 Count | 字典长度 |
|
||||||
|
|
||||||
|
### JSON JToken/JObject/JArray
|
||||||
|
| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 |
|
||||||
|
| - | - | - | - | - |
|
||||||
|
| a.Count | - | - | jsonb_array_length(coalesce(a, '[])) | json数组类型的长度 |
|
||||||
|
| a.Any() | - | - | jsonb_array_length(coalesce(a, '[])) > 0 | json数组类型,是否为空 |
|
||||||
|
| a.Contains(b) | - | - | coalesce(a, '{}') @> b::jsonb | json中是否包含b |
|
||||||
|
| a.ContainsKey(b) | - | - | coalesce(a, '{}') ? b | json中是否包含键b |
|
||||||
|
| a.Concat(b) | - | - | coalesce(a, '{}') || b::jsonb | 连接两个json |
|
||||||
|
| Parse(a) | - | - | a::jsonb | 转化字符串为json类型 |
|
||||||
|
|
||||||
### 字符串对象
|
### 字符串对象
|
||||||
| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 |
|
| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 |
|
||||||
| - | - | - | - | - |
|
| - | - | - | - | - |
|
||||||
| string.Empty | '' | '' | '' | 空字符串表示 |
|
| string.Empty | '' | '' | '' | 空字符串表示 |
|
||||||
|
| string.IsNullOrEmpty(a) | (a is null or a = '') | (a is null or a = '') | (a is null or a = '') | 空字符串表示 |
|
||||||
| a.CompareTo(b) | strcmp(a, b) | - | - | 比较a和b大小 |
|
| a.CompareTo(b) | strcmp(a, b) | - | - | 比较a和b大小 |
|
||||||
| a.Contains('b') | a like '%b%' | a like '%b%' | - | a是否包含b |
|
| a.Contains('b') | a like '%b%' | a like '%b%' | - | a是否包含b |
|
||||||
| a.EndsWith('b') | a like '%b' | a like '%b' | - | a尾部是否包含b |
|
| a.EndsWith('b') | a like '%b' | a like '%b' | - | a尾部是否包含b |
|
||||||
|
92
FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs
Normal file
92
FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Npgsql;
|
||||||
|
using Npgsql.LegacyPostgis;
|
||||||
|
using NpgsqlTypes;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.MySqlExpression {
|
||||||
|
public class OtherTest {
|
||||||
|
|
||||||
|
ISelect<TableAllType> select => g.mysql.Select<TableAllType>();
|
||||||
|
|
||||||
|
public OtherTest() {
|
||||||
|
NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Array() {
|
||||||
|
//in not in
|
||||||
|
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 sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
|
||||||
|
|
||||||
|
var inarray = new[] { 1, 2, 3 };
|
||||||
|
var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList();
|
||||||
|
var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList();
|
||||||
|
var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Table(Name = "tb_alltype")]
|
||||||
|
class TableAllType {
|
||||||
|
[Column(IsIdentity = true, IsPrimary = true)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public bool testFieldBool { get; set; }
|
||||||
|
public sbyte testFieldSByte { get; set; }
|
||||||
|
public short testFieldShort { get; set; }
|
||||||
|
public int testFieldInt { get; set; }
|
||||||
|
public long testFieldLong { get; set; }
|
||||||
|
public byte testFieldByte { get; set; }
|
||||||
|
public ushort testFieldUShort { get; set; }
|
||||||
|
public uint testFieldUInt { get; set; }
|
||||||
|
public ulong testFieldULong { get; set; }
|
||||||
|
public double testFieldDouble { get; set; }
|
||||||
|
public float testFieldFloat { get; set; }
|
||||||
|
public decimal testFieldDecimal { get; set; }
|
||||||
|
public TimeSpan testFieldTimeSpan { get; set; }
|
||||||
|
public DateTime testFieldDateTime { get; set; }
|
||||||
|
public byte[] testFieldBytes { get; set; }
|
||||||
|
public string testFieldString { get; set; }
|
||||||
|
public Guid testFieldGuid { get; set; }
|
||||||
|
|
||||||
|
public bool? testFieldBoolNullable { get; set; }
|
||||||
|
public sbyte? testFieldSByteNullable { get; set; }
|
||||||
|
public short? testFieldShortNullable { get; set; }
|
||||||
|
public int? testFieldIntNullable { get; set; }
|
||||||
|
public long? testFielLongNullable { get; set; }
|
||||||
|
public byte? testFieldByteNullable { get; set; }
|
||||||
|
public ushort? testFieldUShortNullable { get; set; }
|
||||||
|
public uint? testFieldUIntNullable { get; set; }
|
||||||
|
public ulong? testFieldULongNullable { get; set; }
|
||||||
|
public double? testFieldDoubleNullable { get; set; }
|
||||||
|
public float? testFieldFloatNullable { get; set; }
|
||||||
|
public decimal? testFieldDecimalNullable { get; set; }
|
||||||
|
public TimeSpan? testFieldTimeSpanNullable { get; set; }
|
||||||
|
public DateTime? testFieldDateTimeNullable { get; set; }
|
||||||
|
public Guid? testFieldGuidNullable { get; set; }
|
||||||
|
|
||||||
|
public MygisPoint testFieldPoint { get; set; }
|
||||||
|
public MygisLineString testFieldLineString { get; set; }
|
||||||
|
public MygisPolygon testFieldPolygon { get; set; }
|
||||||
|
public MygisMultiPoint testFieldMultiPoint { get; set; }
|
||||||
|
public MygisMultiLineString testFieldMultiLineString { get; set; }
|
||||||
|
public MygisMultiPolygon testFieldMultiPolygon { get; set; }
|
||||||
|
|
||||||
|
public TableAllTypeEnumType1 testFieldEnum1 { get; set; }
|
||||||
|
public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; }
|
||||||
|
public TableAllTypeEnumType2 testFieldEnum2 { get; set; }
|
||||||
|
public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TableAllTypeEnumType1 { e1, e2, e3, e5 }
|
||||||
|
[Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 }
|
||||||
|
}
|
||||||
|
}
|
@ -671,5 +671,13 @@ namespace FreeSql.Tests.MySqlExpression {
|
|||||||
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
//WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0)
|
//WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void string_IsNullOrEmpty() {
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList());
|
||||||
|
data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList());
|
||||||
|
data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,16 @@ namespace FreeSql.Tests.PostgreSQLExpression {
|
|||||||
var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToList();
|
var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToList();
|
||||||
var sql2 = select.Where(a => a.testFieldIntArray.Contains(1) == false).ToList();
|
var sql2 = select.Where(a => a.testFieldIntArray.Contains(1) == false).ToList();
|
||||||
|
|
||||||
|
//in not in
|
||||||
|
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 sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
|
||||||
|
|
||||||
|
var inarray = new[] { 1, 2, 3 };
|
||||||
|
var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToSql();
|
||||||
|
var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToSql();
|
||||||
|
var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToSql();
|
||||||
|
|
||||||
var sql3 = select.Where(a => a.testFieldIntArray.Any()).ToList();
|
var sql3 = select.Where(a => a.testFieldIntArray.Any()).ToList();
|
||||||
var sql4 = select.Where(a => a.testFieldIntArray.Any() == false).ToList();
|
var sql4 = select.Where(a => a.testFieldIntArray.Any() == false).ToList();
|
||||||
|
|
||||||
|
@ -671,5 +671,13 @@ namespace FreeSql.Tests.PostgreSQLExpression {
|
|||||||
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
//WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0)
|
//WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void string_IsNullOrEmpty() {
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList());
|
||||||
|
data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList());
|
||||||
|
data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
88
FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs
Normal file
88
FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Npgsql;
|
||||||
|
using Npgsql.LegacyPostgis;
|
||||||
|
using NpgsqlTypes;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.SqlServerExpression {
|
||||||
|
public class OtherTest {
|
||||||
|
|
||||||
|
ISelect<TableAllType> select => g.sqlserver.Select<TableAllType>();
|
||||||
|
|
||||||
|
public OtherTest() {
|
||||||
|
NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Array() {
|
||||||
|
//in not in
|
||||||
|
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 sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
|
||||||
|
|
||||||
|
var inarray = new[] { 1, 2, 3 };
|
||||||
|
var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList();
|
||||||
|
//var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList();
|
||||||
|
var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Table(Name = "tb_alltype")]
|
||||||
|
class TableAllType {
|
||||||
|
[Column(IsIdentity = true, IsPrimary = true)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[Column(Name = "testFieldBool1111")]
|
||||||
|
public bool testFieldBool { get; set; }
|
||||||
|
public sbyte testFieldSByte { get; set; }
|
||||||
|
public short testFieldShort { get; set; }
|
||||||
|
public int testFieldInt { get; set; }
|
||||||
|
public long testFieldLong { get; set; }
|
||||||
|
public byte testFieldByte { get; set; }
|
||||||
|
public ushort testFieldUShort { get; set; }
|
||||||
|
public uint testFieldUInt { get; set; }
|
||||||
|
public ulong testFieldULong { get; set; }
|
||||||
|
public double testFieldDouble { get; set; }
|
||||||
|
public float testFieldFloat { get; set; }
|
||||||
|
public decimal testFieldDecimal { get; set; }
|
||||||
|
public TimeSpan testFieldTimeSpan { get; set; }
|
||||||
|
public DateTime testFieldDateTime { get; set; }
|
||||||
|
public DateTimeOffset testFieldDateTimeOffset { get; set; }
|
||||||
|
public byte[] testFieldBytes { get; set; }
|
||||||
|
public string testFieldString { get; set; }
|
||||||
|
public Guid testFieldGuid { get; set; }
|
||||||
|
|
||||||
|
public bool? testFieldBoolNullable { get; set; }
|
||||||
|
public sbyte? testFieldSByteNullable { get; set; }
|
||||||
|
public short? testFieldShortNullable { get; set; }
|
||||||
|
public int? testFieldIntNullable { get; set; }
|
||||||
|
public long? testFielLongNullable { get; set; }
|
||||||
|
public byte? testFieldByteNullable { get; set; }
|
||||||
|
public ushort? testFieldUShortNullable { get; set; }
|
||||||
|
public uint? testFieldUIntNullable { get; set; }
|
||||||
|
public ulong? testFieldULongNullable { get; set; }
|
||||||
|
public double? testFieldDoubleNullable { get; set; }
|
||||||
|
public float? testFieldFloatNullable { get; set; }
|
||||||
|
public decimal? testFieldDecimalNullable { get; set; }
|
||||||
|
public TimeSpan? testFieldTimeSpanNullable { get; set; }
|
||||||
|
public DateTime? testFieldDateTimeNullable { get; set; }
|
||||||
|
public DateTimeOffset? testFieldDateTimeNullableOffset { get; set; }
|
||||||
|
public Guid? testFieldGuidNullable { get; set; }
|
||||||
|
|
||||||
|
public TableAllTypeEnumType1 testFieldEnum1 { get; set; }
|
||||||
|
public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; }
|
||||||
|
public TableAllTypeEnumType2 testFieldEnum2 { get; set; }
|
||||||
|
public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TableAllTypeEnumType1 { e1, e2, e3, e5 }
|
||||||
|
[Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 }
|
||||||
|
}
|
||||||
|
}
|
@ -227,11 +227,19 @@ namespace FreeSql.Tests.SqlServerExpression {
|
|||||||
//data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList());
|
//data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList());
|
||||||
//data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList());
|
//data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList());
|
||||||
//data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList());
|
//data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList());
|
||||||
|
|
||||||
//data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList());
|
//data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList());
|
||||||
//data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList());
|
//data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList());
|
||||||
//data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList());
|
//data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList());
|
||||||
//data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList());
|
//data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void string_IsNullOrEmpty() {
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList());
|
||||||
|
//data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList());
|
||||||
|
data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,6 +194,7 @@ namespace FreeSql.Internal {
|
|||||||
|
|
||||||
internal string ExpressionLambdaToSql(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
|
internal string ExpressionLambdaToSql(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||||
switch (exp.NodeType) {
|
switch (exp.NodeType) {
|
||||||
|
case ExpressionType.Not: return $"not({ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
case ExpressionType.Convert: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
case ExpressionType.Convert: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace FreeSql.Internal.CommonProvider {
|
namespace FreeSql.Internal.CommonProvider {
|
||||||
abstract partial class AdoProvider : IAdo {
|
abstract partial class AdoProvider : IAdo {
|
||||||
@ -30,28 +31,31 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
this._log = log;
|
this._log = log;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoggerException(ObjectPool<DbConnection> pool, DbCommand cmd, Exception e, DateTime dt, string logtxt, bool isThrowException = true) {
|
void LoggerException(ObjectPool<DbConnection> pool, DbCommand cmd, Exception e, DateTime dt, StringBuilder logtxt, bool isThrowException = true) {
|
||||||
if (IsTracePerformance) {
|
if (IsTracePerformance) {
|
||||||
TimeSpan ts = DateTime.Now.Subtract(dt);
|
TimeSpan ts = DateTime.Now.Subtract(dt);
|
||||||
if (e == null && ts.TotalMilliseconds > 100)
|
if (e == null && ts.TotalMilliseconds > 100)
|
||||||
_log.LogWarning(logtxt = $"{pool.Policy.Name}执行SQL语句耗时过长{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n{logtxt}");
|
_log.LogWarning(logtxt.Insert(0, $"{pool.Policy.Name}(执行SQL)语句耗时过长{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString());
|
||||||
|
else
|
||||||
|
logtxt.Insert(0, $"{pool.Policy.Name}(执行SQL)耗时{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n").ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e == null) {
|
if (e == null) {
|
||||||
AopCommandExecuted?.Invoke(cmd, logtxt);
|
AopCommandExecuted?.Invoke(cmd, logtxt.ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string log = $"{pool.Policy.Name}数据库出错(执行SQL)〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\r\n{cmd.CommandText}\r\n";
|
StringBuilder log = new StringBuilder();
|
||||||
|
log.Append(pool.Policy.Name).Append("数据库出错(执行SQL)〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\r\n").Append(cmd.CommandText).Append("\r\n");
|
||||||
foreach (DbParameter parm in cmd.Parameters)
|
foreach (DbParameter parm in cmd.Parameters)
|
||||||
log += parm.ParameterName.PadRight(20, ' ') + " = " + ((parm.Value ?? DBNull.Value) == DBNull.Value ? "NULL" : parm.Value) + "\r\n";
|
log.Append(parm.ParameterName.PadRight(20, ' ')).Append(" = ").Append((parm.Value ?? DBNull.Value) == DBNull.Value ? "NULL" : parm.Value).Append("\r\n");
|
||||||
|
|
||||||
log += e.Message;
|
log.Append(e.Message);
|
||||||
_log.LogError(log);
|
_log.LogError(log.ToString());
|
||||||
|
|
||||||
RollbackTransaction();
|
RollbackTransaction();
|
||||||
|
|
||||||
AopCommandExecuted?.Invoke(cmd, log);
|
AopCommandExecuted?.Invoke(cmd, log.ToString());
|
||||||
|
|
||||||
cmd.Parameters.Clear();
|
cmd.Parameters.Clear();
|
||||||
if (isThrowException) throw e;
|
if (isThrowException) throw e;
|
||||||
@ -77,11 +81,11 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
}
|
}
|
||||||
public void ExecuteReader(Action<DbDataReader> readerHander, string sql, object parms = null) => ExecuteReader(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
public void ExecuteReader(Action<DbDataReader> readerHander, string sql, object parms = null) => ExecuteReader(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||||
public void ExecuteReader(Action<DbDataReader> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
public void ExecuteReader(Action<DbDataReader> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||||
DateTime dt = DateTime.Now;
|
var dt = DateTime.Now;
|
||||||
string logtxt = "";
|
var logtxt = new StringBuilder();
|
||||||
DateTime logtxt_dt = DateTime.Now;
|
var logtxt_dt = DateTime.Now;
|
||||||
var pool = this.MasterPool;
|
var pool = this.MasterPool;
|
||||||
bool isSlave = false;
|
var isSlave = false;
|
||||||
|
|
||||||
//读写分离规则
|
//读写分离规则
|
||||||
if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) {
|
if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
@ -99,8 +103,8 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object<DbConnection> conn = null;
|
Object<DbConnection> conn = null;
|
||||||
var pc = PrepareCommand(cmdType, cmdText, cmdParms, ref logtxt);
|
var pc = PrepareCommand(cmdType, cmdText, cmdParms, logtxt);
|
||||||
if (IsTracePerformance) logtxt += $"PrepareCommand: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
if (IsTracePerformance) logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
Exception ex = null;
|
Exception ex = null;
|
||||||
try {
|
try {
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
@ -117,7 +121,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
|
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
|
||||||
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms";
|
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||||
}
|
}
|
||||||
LoggerException(pool, pc.cmd, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false);
|
LoggerException(pool, pc.cmd, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false);
|
||||||
pc.cmd.Parameters.Clear();
|
pc.cmd.Parameters.Clear();
|
||||||
@ -129,15 +133,15 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = pool.Get()).Value;
|
if (pc.cmd.Connection == null) pc.cmd.Connection = (conn = pool.Get()).Value;
|
||||||
}
|
}
|
||||||
if (IsTracePerformance) {
|
if (IsTracePerformance) {
|
||||||
logtxt += $"Open: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
logtxt.Append("Open: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
logtxt_dt = DateTime.Now;
|
logtxt_dt = DateTime.Now;
|
||||||
}
|
}
|
||||||
using (var dr = pc.cmd.ExecuteReader()) {
|
using (var dr = pc.cmd.ExecuteReader()) {
|
||||||
if (IsTracePerformance) logtxt += $"ExecuteReader: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
if (IsTracePerformance) logtxt.Append("ExecuteReader: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
while (true) {
|
while (true) {
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
bool isread = dr.Read();
|
bool isread = dr.Read();
|
||||||
if (IsTracePerformance) logtxt += $" dr.Read: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
if (IsTracePerformance) logtxt.Append(" dr.Read: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
if (isread == false) break;
|
if (isread == false) break;
|
||||||
|
|
||||||
if (readerHander != null) {
|
if (readerHander != null) {
|
||||||
@ -146,17 +150,17 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
logtxt_dt = DateTime.Now;
|
logtxt_dt = DateTime.Now;
|
||||||
values = new object[dr.FieldCount];
|
values = new object[dr.FieldCount];
|
||||||
dr.GetValues(values);
|
dr.GetValues(values);
|
||||||
logtxt += $" dr.GetValues: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
logtxt.Append(" dr.GetValues: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
logtxt_dt = DateTime.Now;
|
logtxt_dt = DateTime.Now;
|
||||||
}
|
}
|
||||||
readerHander(dr);
|
readerHander(dr);
|
||||||
if (IsTracePerformance) logtxt += $" readerHander: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms ({string.Join(",", values)})\r\n";
|
if (IsTracePerformance) logtxt.Append(" readerHander: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms (").Append(string.Join(", ", values)).Append(")\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
dr.Close();
|
dr.Close();
|
||||||
}
|
}
|
||||||
if (IsTracePerformance) logtxt += $"ExecuteReader_dispose: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
if (IsTracePerformance) logtxt.Append("ExecuteReader_dispose: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
} catch (Exception ex2) {
|
} catch (Exception ex2) {
|
||||||
ex = ex2;
|
ex = ex2;
|
||||||
}
|
}
|
||||||
@ -164,7 +168,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
|
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
|
||||||
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms";
|
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||||
}
|
}
|
||||||
LoggerException(pool, pc.cmd, ex, dt, logtxt);
|
LoggerException(pool, pc.cmd, ex, dt, logtxt);
|
||||||
pc.cmd.Parameters.Clear();
|
pc.cmd.Parameters.Clear();
|
||||||
@ -193,11 +197,11 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
}
|
}
|
||||||
public int ExecuteNonQuery(string sql, object parms = null) => ExecuteNonQuery(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
public int ExecuteNonQuery(string sql, object parms = null) => ExecuteNonQuery(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||||
public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||||
DateTime dt = DateTime.Now;
|
var dt = DateTime.Now;
|
||||||
string logtxt = "";
|
var logtxt = new StringBuilder();
|
||||||
DateTime logtxt_dt = DateTime.Now;
|
var logtxt_dt = DateTime.Now;
|
||||||
Object<DbConnection> conn = null;
|
Object<DbConnection> conn = null;
|
||||||
var pc = PrepareCommand(cmdType, cmdText, cmdParms, ref logtxt);
|
var pc = PrepareCommand(cmdType, cmdText, cmdParms, logtxt);
|
||||||
int val = 0;
|
int val = 0;
|
||||||
Exception ex = null;
|
Exception ex = null;
|
||||||
try {
|
try {
|
||||||
@ -210,7 +214,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
|
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
|
||||||
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms";
|
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||||
}
|
}
|
||||||
LoggerException(this.MasterPool, pc.cmd, ex, dt, logtxt);
|
LoggerException(this.MasterPool, pc.cmd, ex, dt, logtxt);
|
||||||
pc.cmd.Parameters.Clear();
|
pc.cmd.Parameters.Clear();
|
||||||
@ -218,11 +222,11 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
}
|
}
|
||||||
public object ExecuteScalar(string sql, object parms = null) => ExecuteScalar(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
public object ExecuteScalar(string sql, object parms = null) => ExecuteScalar(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||||
public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||||
DateTime dt = DateTime.Now;
|
var dt = DateTime.Now;
|
||||||
string logtxt = "";
|
var logtxt = new StringBuilder();
|
||||||
DateTime logtxt_dt = DateTime.Now;
|
var logtxt_dt = DateTime.Now;
|
||||||
Object<DbConnection> conn = null;
|
Object<DbConnection> conn = null;
|
||||||
var pc = PrepareCommand(cmdType, cmdText, cmdParms, ref logtxt);
|
var pc = PrepareCommand(cmdType, cmdText, cmdParms, logtxt);
|
||||||
object val = null;
|
object val = null;
|
||||||
Exception ex = null;
|
Exception ex = null;
|
||||||
try {
|
try {
|
||||||
@ -235,14 +239,14 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
|
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
|
||||||
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms";
|
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||||
}
|
}
|
||||||
LoggerException(this.MasterPool, pc.cmd, ex, dt, logtxt);
|
LoggerException(this.MasterPool, pc.cmd, ex, dt, logtxt);
|
||||||
pc.cmd.Parameters.Clear();
|
pc.cmd.Parameters.Clear();
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
private (DbTransaction tran, DbCommand cmd) PrepareCommand(CommandType cmdType, string cmdText, DbParameter[] cmdParms, ref string logtxt) {
|
private (DbTransaction tran, DbCommand cmd) PrepareCommand(CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) {
|
||||||
var dt = DateTime.Now;
|
var dt = DateTime.Now;
|
||||||
DbCommand cmd = CreateCommand();
|
DbCommand cmd = CreateCommand();
|
||||||
cmd.CommandType = cmdType;
|
cmd.CommandType = cmdType;
|
||||||
@ -257,18 +261,18 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tran = TransactionCurrentThread;
|
var tran = TransactionCurrentThread;
|
||||||
if (IsTracePerformance) logtxt += $" PrepareCommand_part1: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms cmdParms: {cmd.Parameters.Count}\r\n";
|
if (IsTracePerformance) logtxt.Append(" PrepareCommand_part1: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n");
|
||||||
|
|
||||||
if (tran != null) {
|
if (tran != null) {
|
||||||
if (IsTracePerformance) dt = DateTime.Now;
|
if (IsTracePerformance) dt = DateTime.Now;
|
||||||
cmd.Connection = tran.Connection;
|
cmd.Connection = tran.Connection;
|
||||||
cmd.Transaction = tran;
|
cmd.Transaction = tran;
|
||||||
if (IsTracePerformance) logtxt += $" PrepareCommand_tran!=null: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
if (IsTracePerformance) logtxt.Append(" PrepareCommand_tran!=null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsTracePerformance) dt = DateTime.Now;
|
if (IsTracePerformance) dt = DateTime.Now;
|
||||||
AutoCommitTransaction();
|
AutoCommitTransaction();
|
||||||
if (IsTracePerformance) logtxt += $" AutoCommitTransaction: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
if (IsTracePerformance) logtxt.Append(" AutoCommitTransaction: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
|
|
||||||
AopCommandExecuting?.Invoke(cmd);
|
AopCommandExecuting?.Invoke(cmd);
|
||||||
return (tran, cmd);
|
return (tran, cmd);
|
||||||
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace FreeSql.Internal.CommonProvider {
|
namespace FreeSql.Internal.CommonProvider {
|
||||||
@ -28,11 +29,11 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
}
|
}
|
||||||
public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, string sql, object parms = null) => ExecuteReaderAsync(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, string sql, object parms = null) => ExecuteReaderAsync(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||||
async public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
async public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||||
DateTime dt = DateTime.Now;
|
var dt = DateTime.Now;
|
||||||
string logtxt = "";
|
var logtxt = new StringBuilder();
|
||||||
DateTime logtxt_dt = DateTime.Now;
|
var logtxt_dt = DateTime.Now;
|
||||||
var pool = this.MasterPool;
|
var pool = this.MasterPool;
|
||||||
bool isSlave = false;
|
var isSlave = false;
|
||||||
|
|
||||||
//读写分离规则
|
//读写分离规则
|
||||||
if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) {
|
if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
@ -50,8 +51,8 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object<DbConnection> conn = null;
|
Object<DbConnection> conn = null;
|
||||||
var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, ref logtxt);
|
var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, logtxt);
|
||||||
if (IsTracePerformance) logtxt += $"PrepareCommand: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
if (IsTracePerformance) logtxt.Append("PrepareCommandAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
Exception ex = null;
|
Exception ex = null;
|
||||||
try {
|
try {
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
@ -68,7 +69,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
|
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
|
||||||
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms";
|
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||||
}
|
}
|
||||||
LoggerException(pool, cmd, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false);
|
LoggerException(pool, cmd, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false);
|
||||||
cmd.Parameters.Clear();
|
cmd.Parameters.Clear();
|
||||||
@ -80,15 +81,15 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (cmd.Connection == null) cmd.Connection = (conn = await pool.GetAsync()).Value;
|
if (cmd.Connection == null) cmd.Connection = (conn = await pool.GetAsync()).Value;
|
||||||
}
|
}
|
||||||
if (IsTracePerformance) {
|
if (IsTracePerformance) {
|
||||||
logtxt += $"Open: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
logtxt.Append("OpenAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
logtxt_dt = DateTime.Now;
|
logtxt_dt = DateTime.Now;
|
||||||
}
|
}
|
||||||
using (var dr = await cmd.ExecuteReaderAsync()) {
|
using (var dr = await cmd.ExecuteReaderAsync()) {
|
||||||
if (IsTracePerformance) logtxt += $"ExecuteReader: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
if (IsTracePerformance) logtxt.Append("ExecuteReaderAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
while (true) {
|
while (true) {
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
bool isread = await dr.ReadAsync();
|
bool isread = await dr.ReadAsync();
|
||||||
if (IsTracePerformance) logtxt += $" dr.Read: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
if (IsTracePerformance) logtxt.Append(" dr.ReadAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
if (isread == false) break;
|
if (isread == false) break;
|
||||||
|
|
||||||
if (readerHander != null) {
|
if (readerHander != null) {
|
||||||
@ -97,17 +98,17 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
logtxt_dt = DateTime.Now;
|
logtxt_dt = DateTime.Now;
|
||||||
values = new object[dr.FieldCount];
|
values = new object[dr.FieldCount];
|
||||||
for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync<object>(a);
|
for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync<object>(a);
|
||||||
logtxt += $" dr.GetValues: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
logtxt.Append(" dr.GetValues: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
logtxt_dt = DateTime.Now;
|
logtxt_dt = DateTime.Now;
|
||||||
}
|
}
|
||||||
await readerHander(dr);
|
await readerHander(dr);
|
||||||
if (IsTracePerformance) logtxt += $" readerHander: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms ({string.Join(",", values)})\r\n";
|
if (IsTracePerformance) logtxt.Append(" readerHanderAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms (").Append(string.Join(", ", values)).Append(")\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
dr.Close();
|
dr.Close();
|
||||||
}
|
}
|
||||||
if (IsTracePerformance) logtxt += $"ExecuteReader_dispose: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
if (IsTracePerformance) logtxt.Append("ExecuteReaderAsync_dispose: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n");
|
||||||
} catch (Exception ex2) {
|
} catch (Exception ex2) {
|
||||||
ex = ex2;
|
ex = ex2;
|
||||||
}
|
}
|
||||||
@ -115,7 +116,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
|
ReturnConnection(pool, conn, ex); //pool.Return(conn, ex);
|
||||||
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms";
|
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||||
}
|
}
|
||||||
LoggerException(pool, cmd, ex, dt, logtxt);
|
LoggerException(pool, cmd, ex, dt, logtxt);
|
||||||
cmd.Parameters.Clear();
|
cmd.Parameters.Clear();
|
||||||
@ -144,11 +145,11 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
}
|
}
|
||||||
public Task<int> ExecuteNonQueryAsync(string sql, object parms = null) => ExecuteNonQueryAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
public Task<int> ExecuteNonQueryAsync(string sql, object parms = null) => ExecuteNonQueryAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||||
async public Task<int> ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
async public Task<int> ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||||
DateTime dt = DateTime.Now;
|
var dt = DateTime.Now;
|
||||||
string logtxt = "";
|
var logtxt = new StringBuilder();
|
||||||
Object<DbConnection> conn = null;
|
|
||||||
var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, ref logtxt);
|
|
||||||
var logtxt_dt = DateTime.Now;
|
var logtxt_dt = DateTime.Now;
|
||||||
|
Object<DbConnection> conn = null;
|
||||||
|
var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, logtxt);
|
||||||
int val = 0;
|
int val = 0;
|
||||||
Exception ex = null;
|
Exception ex = null;
|
||||||
try {
|
try {
|
||||||
@ -161,7 +162,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
|
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
|
||||||
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms";
|
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||||
}
|
}
|
||||||
LoggerException(this.MasterPool, cmd, ex, dt, logtxt);
|
LoggerException(this.MasterPool, cmd, ex, dt, logtxt);
|
||||||
cmd.Parameters.Clear();
|
cmd.Parameters.Clear();
|
||||||
@ -170,10 +171,10 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
public Task<object> ExecuteScalarAsync(string sql, object parms = null) => ExecuteScalarAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
public Task<object> ExecuteScalarAsync(string sql, object parms = null) => ExecuteScalarAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
|
||||||
async public Task<object> ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
async public Task<object> ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
|
||||||
var dt = DateTime.Now;
|
var dt = DateTime.Now;
|
||||||
var logtxt = "";
|
var logtxt = new StringBuilder();
|
||||||
Object<DbConnection> conn = null;
|
|
||||||
var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, ref logtxt);
|
|
||||||
var logtxt_dt = DateTime.Now;
|
var logtxt_dt = DateTime.Now;
|
||||||
|
Object<DbConnection> conn = null;
|
||||||
|
var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, logtxt);
|
||||||
object val = null;
|
object val = null;
|
||||||
Exception ex = null;
|
Exception ex = null;
|
||||||
try {
|
try {
|
||||||
@ -186,14 +187,14 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
if (IsTracePerformance) logtxt_dt = DateTime.Now;
|
||||||
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
|
ReturnConnection(MasterPool, conn, ex); //this.MasterPool.Return(conn, ex);
|
||||||
if (IsTracePerformance) logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms";
|
if (IsTracePerformance) logtxt.Append("ReleaseConnection: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms");
|
||||||
}
|
}
|
||||||
LoggerException(this.MasterPool, cmd, ex, dt, logtxt);
|
LoggerException(this.MasterPool, cmd, ex, dt, logtxt);
|
||||||
cmd.Parameters.Clear();
|
cmd.Parameters.Clear();
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DbCommand PrepareCommandAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, ref string logtxt) {
|
private DbCommand PrepareCommandAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) {
|
||||||
DateTime dt = DateTime.Now;
|
DateTime dt = DateTime.Now;
|
||||||
DbCommand cmd = CreateCommand();
|
DbCommand cmd = CreateCommand();
|
||||||
cmd.CommandType = cmdType;
|
cmd.CommandType = cmdType;
|
||||||
@ -207,7 +208,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsTracePerformance) logtxt += $" PrepareCommand_tran==null: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms cmdParms: {cmd.Parameters.Count}\r\n";
|
if (IsTracePerformance) logtxt.Append(" PrepareCommand_tran==null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n");
|
||||||
|
|
||||||
AopCommandExecuting?.Invoke(cmd);
|
AopCommandExecuting?.Invoke(cmd);
|
||||||
return cmd;
|
return cmd;
|
||||||
|
@ -4,6 +4,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace FreeSql.MySql {
|
namespace FreeSql.MySql {
|
||||||
class MySqlExpression : CommonExpression {
|
class MySqlExpression : CommonExpression {
|
||||||
@ -11,6 +12,41 @@ namespace FreeSql.MySql {
|
|||||||
public MySqlExpression(CommonUtils common) : base(common) { }
|
public MySqlExpression(CommonUtils common) : base(common) { }
|
||||||
|
|
||||||
internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
|
internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||||
|
switch (exp.NodeType) {
|
||||||
|
case ExpressionType.Call:
|
||||||
|
var callExp = exp as MethodCallExpression;
|
||||||
|
var objExp = callExp.Object;
|
||||||
|
var objType = objExp?.Type;
|
||||||
|
if (objType?.FullName == "System.Byte[]") return null;
|
||||||
|
|
||||||
|
var argIndex = 0;
|
||||||
|
if (objType == null && callExp.Method.DeclaringType.FullName == typeof(Enumerable).FullName) {
|
||||||
|
objExp = callExp.Arguments.FirstOrDefault();
|
||||||
|
objType = objExp?.Type;
|
||||||
|
argIndex++;
|
||||||
|
}
|
||||||
|
if (objType == null) objType = callExp.Method.DeclaringType;
|
||||||
|
if (objType != null) {
|
||||||
|
var left = objExp == null ? null : ExpressionLambdaToSql(objExp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
|
if (objType.IsArray == true) {
|
||||||
|
switch (callExp.Method.Name) {
|
||||||
|
case "Contains":
|
||||||
|
//判断 in
|
||||||
|
return $"({ExpressionLambdaToSql(callExp.Arguments[argIndex], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}) in {left}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ExpressionType.NewArrayInit:
|
||||||
|
var arrExp = exp as NewArrayExpression;
|
||||||
|
var arrSb = new StringBuilder();
|
||||||
|
arrSb.Append("(");
|
||||||
|
for (var a = 0; a < arrExp.Expressions.Count; a++) {
|
||||||
|
if (a > 0) arrSb.Append(",");
|
||||||
|
arrSb.Append(ExpressionLambdaToSql(arrExp.Expressions[a], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName));
|
||||||
|
}
|
||||||
|
return arrSb.Append(")").ToString();
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,64 +118,72 @@ namespace FreeSql.MySql {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
|
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||||
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
if (exp.Object == null) {
|
||||||
switch (exp.Method.Name) {
|
switch (exp.Method.Name) {
|
||||||
case "StartsWith":
|
case "IsNullOrEmpty":
|
||||||
case "EndsWith":
|
var arg1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
case "Contains":
|
return $"({arg1} is null or {arg1} = '')";
|
||||||
var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
}
|
||||||
if (args0Value == "NULL") return $"({left}) IS NULL";
|
} else {
|
||||||
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"concat({args0Value}, '%')")}";
|
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"concat('%', {args0Value})")}";
|
switch (exp.Method.Name) {
|
||||||
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
|
case "StartsWith":
|
||||||
return $"({left}) LIKE concat('%', {args0Value}, '%')";
|
case "EndsWith":
|
||||||
case "ToLower": return $"lower({left})";
|
case "Contains":
|
||||||
case "ToUpper": return $"upper({left})";
|
var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
case "Substring":
|
if (args0Value == "NULL") return $"({left}) IS NULL";
|
||||||
var substrArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"concat({args0Value}, '%')")}";
|
||||||
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
|
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"concat('%', {args0Value})")}";
|
||||||
else substrArgs1 += "+1";
|
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
|
||||||
if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})";
|
return $"({left}) LIKE concat('%', {args0Value}, '%')";
|
||||||
return $"substr({left}, {substrArgs1}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
case "ToLower": return $"lower({left})";
|
||||||
case "IndexOf":
|
case "ToUpper": return $"upper({left})";
|
||||||
var indexOfFindStr = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
case "Substring":
|
||||||
if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") {
|
var substrArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
var locateArgs1 = ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
|
||||||
if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString();
|
else substrArgs1 += "+1";
|
||||||
else locateArgs1 += "+1";
|
if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})";
|
||||||
return $"(locate({left}, {indexOfFindStr}, {locateArgs1})-1)";
|
return $"substr({left}, {substrArgs1}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
}
|
case "IndexOf":
|
||||||
return $"(locate({left}, {indexOfFindStr})-1)";
|
var indexOfFindStr = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
case "PadLeft":
|
if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") {
|
||||||
if (exp.Arguments.Count == 1) return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
var locateArgs1 = ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString();
|
||||||
case "PadRight":
|
else locateArgs1 += "+1";
|
||||||
if (exp.Arguments.Count == 1) return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
return $"(locate({left}, {indexOfFindStr}, {locateArgs1})-1)";
|
||||||
return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
|
||||||
case "Trim":
|
|
||||||
case "TrimStart":
|
|
||||||
case "TrimEnd":
|
|
||||||
if (exp.Arguments.Count == 0) {
|
|
||||||
if (exp.Method.Name == "Trim") return $"trim({left})";
|
|
||||||
if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
|
|
||||||
if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
|
|
||||||
}
|
|
||||||
foreach (var argsTrim02 in exp.Arguments) {
|
|
||||||
var argsTrim01s = new[] { argsTrim02 };
|
|
||||||
if (argsTrim02.NodeType == ExpressionType.NewArrayInit) {
|
|
||||||
var arritem = argsTrim02 as NewArrayExpression;
|
|
||||||
argsTrim01s = arritem.Expressions.ToArray();
|
|
||||||
}
|
}
|
||||||
foreach (var argsTrim01 in argsTrim01s) {
|
return $"(locate({left}, {indexOfFindStr})-1)";
|
||||||
if (exp.Method.Name == "Trim") left = $"trim({ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} from {left})";
|
case "PadLeft":
|
||||||
if (exp.Method.Name == "TrimStart") left = $"trim(leading {ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} from {left})";
|
if (exp.Arguments.Count == 1) return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
if (exp.Method.Name == "TrimEnd") left = $"trim(trailing {ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} from {left})";
|
return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
case "PadRight":
|
||||||
|
if (exp.Arguments.Count == 1) return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
case "Trim":
|
||||||
|
case "TrimStart":
|
||||||
|
case "TrimEnd":
|
||||||
|
if (exp.Arguments.Count == 0) {
|
||||||
|
if (exp.Method.Name == "Trim") return $"trim({left})";
|
||||||
|
if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
|
||||||
|
if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
|
||||||
}
|
}
|
||||||
}
|
foreach (var argsTrim02 in exp.Arguments) {
|
||||||
return left;
|
var argsTrim01s = new[] { argsTrim02 };
|
||||||
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
if (argsTrim02.NodeType == ExpressionType.NewArrayInit) {
|
||||||
case "CompareTo": return $"strcmp({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
var arritem = argsTrim02 as NewArrayExpression;
|
||||||
case "Equals": return $"({left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
argsTrim01s = arritem.Expressions.ToArray();
|
||||||
|
}
|
||||||
|
foreach (var argsTrim01 in argsTrim01s) {
|
||||||
|
if (exp.Method.Name == "Trim") left = $"trim({ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} from {left})";
|
||||||
|
if (exp.Method.Name == "TrimStart") left = $"trim(leading {ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} from {left})";
|
||||||
|
if (exp.Method.Name == "TrimEnd") left = $"trim(trailing {ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} from {left})";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return left;
|
||||||
|
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
case "CompareTo": return $"strcmp({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
case "Equals": return $"({left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new Exception($"MySqlExpression 未现实函数表达式 {exp} 解析");
|
throw new Exception($"MySqlExpression 未现实函数表达式 {exp} 解析");
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ namespace FreeSql.PostgreSQL {
|
|||||||
switch (exp.NodeType) {
|
switch (exp.NodeType) {
|
||||||
case ExpressionType.ArrayLength:
|
case ExpressionType.ArrayLength:
|
||||||
var arrOperExp = ExpressionLambdaToSql((exp as UnaryExpression).Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
var arrOperExp = ExpressionLambdaToSql((exp as UnaryExpression).Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}])";
|
if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)";
|
||||||
return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end";
|
return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end";
|
||||||
case ExpressionType.Call:
|
case ExpressionType.Call:
|
||||||
var callExp = exp as MethodCallExpression;
|
var callExp = exp as MethodCallExpression;
|
||||||
@ -34,18 +34,30 @@ namespace FreeSql.PostgreSQL {
|
|||||||
if (objType != null) {
|
if (objType != null) {
|
||||||
var left = objExp == null ? null : ExpressionLambdaToSql(objExp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
var left = objExp == null ? null : ExpressionLambdaToSql(objExp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
if (objType.IsArray == true) {
|
if (objType.IsArray == true) {
|
||||||
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
|
|
||||||
switch (callExp.Method.Name) {
|
switch (callExp.Method.Name) {
|
||||||
case "Any": return $"(case when {left} is null then 0 else array_length({left},1) end > 0)";
|
case "Any":
|
||||||
case "Contains": return $"({left} @> array[{ExpressionLambdaToSql(callExp.Arguments[argIndex], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}])";
|
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
|
||||||
|
return $"(case when {left} is null then 0 else array_length({left},1) end > 0)";
|
||||||
|
case "Contains":
|
||||||
|
//判断 in 或 array @> array
|
||||||
|
var right1 = ExpressionLambdaToSql(callExp.Arguments[argIndex], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
|
if (left.StartsWith("array[") || left.EndsWith("]"))
|
||||||
|
return $"{right1} in ({left.Substring(6, left.Length - 7)})";
|
||||||
|
if (left.StartsWith("(") || left.EndsWith(")"))
|
||||||
|
return $"{right1} in {left}";
|
||||||
|
if (right1.StartsWith("(") || right1.EndsWith(")")) right1 = $"array[{right1.TrimStart('(').TrimEnd(')')}]";
|
||||||
|
return $"({left} @> array[{right1}])";
|
||||||
case "Concat":
|
case "Concat":
|
||||||
|
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
|
||||||
var right2 = ExpressionLambdaToSql(callExp.Arguments[argIndex], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
var right2 = ExpressionLambdaToSql(callExp.Arguments[argIndex], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]";
|
if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]";
|
||||||
return $"({left} || {right2})";
|
return $"({left} || {right2})";
|
||||||
case "GetLength":
|
case "GetLength":
|
||||||
case "GetLongLength":
|
case "GetLongLength":
|
||||||
case "Length":
|
case "Length":
|
||||||
case "Count": return $"case when {left} is null then 0 else array_length({left},1) end";
|
case "Count":
|
||||||
|
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
|
||||||
|
return $"case when {left} is null then 0 else array_length({left},1) end";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (objType.FullName) {
|
switch (objType.FullName) {
|
||||||
@ -92,8 +104,8 @@ namespace FreeSql.PostgreSQL {
|
|||||||
var memParentExp = memExp.Expression?.Type;
|
var memParentExp = memExp.Expression?.Type;
|
||||||
if (memParentExp?.FullName == "System.Byte[]") return null;
|
if (memParentExp?.FullName == "System.Byte[]") return null;
|
||||||
if (memParentExp != null) {
|
if (memParentExp != null) {
|
||||||
var left = ExpressionLambdaToSql(memExp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
|
||||||
if (memParentExp.IsArray == true) {
|
if (memParentExp.IsArray == true) {
|
||||||
|
var left = ExpressionLambdaToSql(memExp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
|
if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]";
|
||||||
switch (memExp.Member.Name) {
|
switch (memExp.Member.Name) {
|
||||||
case "Length":
|
case "Length":
|
||||||
@ -104,12 +116,14 @@ namespace FreeSql.PostgreSQL {
|
|||||||
case "Newtonsoft.Json.Linq.JToken":
|
case "Newtonsoft.Json.Linq.JToken":
|
||||||
case "Newtonsoft.Json.Linq.JObject":
|
case "Newtonsoft.Json.Linq.JObject":
|
||||||
case "Newtonsoft.Json.Linq.JArray":
|
case "Newtonsoft.Json.Linq.JArray":
|
||||||
|
var left = ExpressionLambdaToSql(memExp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
switch (memExp.Member.Name) {
|
switch (memExp.Member.Name) {
|
||||||
case "Count": return $"jsonb_array_length(coalesce({left},'[]'))";
|
case "Count": return $"jsonb_array_length(coalesce({left},'[]'))";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (memParentExp.FullName == typeof(Dictionary<string, string>).FullName) {
|
if (memParentExp.FullName == typeof(Dictionary<string, string>).FullName) {
|
||||||
|
var left = ExpressionLambdaToSql(memExp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
switch (memExp.Member.Name) {
|
switch (memExp.Member.Name) {
|
||||||
case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end";
|
case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end";
|
||||||
case "Keys": return $"akeys({left})";
|
case "Keys": return $"akeys({left})";
|
||||||
@ -199,66 +213,74 @@ namespace FreeSql.PostgreSQL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
|
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||||
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
if (exp.Object == null) {
|
||||||
switch (exp.Method.Name) {
|
switch (exp.Method.Name) {
|
||||||
case "StartsWith":
|
case "IsNullOrEmpty":
|
||||||
case "EndsWith":
|
var arg1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
case "Contains":
|
return $"({arg1} is null or {arg1} = '')";
|
||||||
var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
}
|
||||||
if (args0Value == "NULL") return $"({left}) IS NULL";
|
} else {
|
||||||
var likeOpt = "LIKE";
|
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
if (exp.Arguments.Count > 1) {
|
switch (exp.Method.Name) {
|
||||||
if (exp.Arguments[1].Type == typeof(bool) ||
|
case "StartsWith":
|
||||||
exp.Arguments[1].Type == typeof(StringComparison) && ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName).Contains("IgnoreCase")) likeOpt = "ILIKE";
|
case "EndsWith":
|
||||||
}
|
case "Contains":
|
||||||
if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}";
|
var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}";
|
if (args0Value == "NULL") return $"({left}) IS NULL";
|
||||||
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
|
var likeOpt = "LIKE";
|
||||||
return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')";
|
if (exp.Arguments.Count > 1) {
|
||||||
case "ToLower": return $"lower({left})";
|
if (exp.Arguments[1].Type == typeof(bool) ||
|
||||||
case "ToUpper": return $"upper({left})";
|
exp.Arguments[1].Type == typeof(StringComparison) && ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName).Contains("IgnoreCase")) likeOpt = "ILIKE";
|
||||||
case "Substring":
|
|
||||||
var substrArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
|
||||||
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
|
|
||||||
else substrArgs1 += "+1";
|
|
||||||
if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})";
|
|
||||||
return $"substr({left}, {substrArgs1}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
|
||||||
case "IndexOf": return $"(strpos({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})-1)";
|
|
||||||
case "PadLeft":
|
|
||||||
if (exp.Arguments.Count == 1) return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
|
||||||
return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
|
||||||
case "PadRight":
|
|
||||||
if (exp.Arguments.Count == 1) return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
|
||||||
return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
|
||||||
case "Trim":
|
|
||||||
case "TrimStart":
|
|
||||||
case "TrimEnd":
|
|
||||||
if (exp.Arguments.Count == 0) {
|
|
||||||
if (exp.Method.Name == "Trim") return $"trim({left})";
|
|
||||||
if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
|
|
||||||
if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
|
|
||||||
}
|
|
||||||
var trimArg1 = "";
|
|
||||||
var trimArg2 = "";
|
|
||||||
foreach (var argsTrim02 in exp.Arguments) {
|
|
||||||
var argsTrim01s = new[] { argsTrim02 };
|
|
||||||
if (argsTrim02.NodeType == ExpressionType.NewArrayInit) {
|
|
||||||
var arritem = argsTrim02 as NewArrayExpression;
|
|
||||||
argsTrim01s = arritem.Expressions.ToArray();
|
|
||||||
}
|
}
|
||||||
foreach (var argsTrim01 in argsTrim01s) {
|
if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::varchar || '%')")}";
|
||||||
var trimChr = ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName).Trim('\'');
|
if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::varchar)")}";
|
||||||
if (trimChr.Length == 1) trimArg1 += trimChr;
|
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
|
||||||
else trimArg2 += $" || ({trimChr})";
|
return $"({left}) {likeOpt} ('%' || ({args0Value})::varchar || '%')";
|
||||||
|
case "ToLower": return $"lower({left})";
|
||||||
|
case "ToUpper": return $"upper({left})";
|
||||||
|
case "Substring":
|
||||||
|
var substrArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
|
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
|
||||||
|
else substrArgs1 += "+1";
|
||||||
|
if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})";
|
||||||
|
return $"substr({left}, {substrArgs1}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
case "IndexOf": return $"(strpos({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})-1)";
|
||||||
|
case "PadLeft":
|
||||||
|
if (exp.Arguments.Count == 1) return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
case "PadRight":
|
||||||
|
if (exp.Arguments.Count == 1) return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
case "Trim":
|
||||||
|
case "TrimStart":
|
||||||
|
case "TrimEnd":
|
||||||
|
if (exp.Arguments.Count == 0) {
|
||||||
|
if (exp.Method.Name == "Trim") return $"trim({left})";
|
||||||
|
if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
|
||||||
|
if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
|
||||||
}
|
}
|
||||||
}
|
var trimArg1 = "";
|
||||||
if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
|
var trimArg2 = "";
|
||||||
if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
|
foreach (var argsTrim02 in exp.Arguments) {
|
||||||
if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
|
var argsTrim01s = new[] { argsTrim02 };
|
||||||
return left;
|
if (argsTrim02.NodeType == ExpressionType.NewArrayInit) {
|
||||||
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
var arritem = argsTrim02 as NewArrayExpression;
|
||||||
case "CompareTo": return $"case when {left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} then 0 when {left} > {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} then 1 else -1 end";
|
argsTrim01s = arritem.Expressions.ToArray();
|
||||||
case "Equals": return $"({left} = ({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})::varchar)";
|
}
|
||||||
|
foreach (var argsTrim01 in argsTrim01s) {
|
||||||
|
var trimChr = ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName).Trim('\'');
|
||||||
|
if (trimChr.Length == 1) trimArg1 += trimChr;
|
||||||
|
else trimArg2 += $" || ({trimChr})";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
|
||||||
|
if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
|
||||||
|
if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
|
||||||
|
return left;
|
||||||
|
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
case "CompareTo": return $"case when {left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} then 0 when {left} > {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)} then 1 else -1 end";
|
||||||
|
case "Equals": return $"({left} = ({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})::varchar)";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
|
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace FreeSql.SqlServer {
|
namespace FreeSql.SqlServer {
|
||||||
class SqlServerExpression : CommonExpression {
|
class SqlServerExpression : CommonExpression {
|
||||||
@ -11,6 +12,41 @@ namespace FreeSql.SqlServer {
|
|||||||
public SqlServerExpression(CommonUtils common) : base(common) { }
|
public SqlServerExpression(CommonUtils common) : base(common) { }
|
||||||
|
|
||||||
internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
|
internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||||
|
switch (exp.NodeType) {
|
||||||
|
case ExpressionType.Call:
|
||||||
|
var callExp = exp as MethodCallExpression;
|
||||||
|
var objExp = callExp.Object;
|
||||||
|
var objType = objExp?.Type;
|
||||||
|
if (objType?.FullName == "System.Byte[]") return null;
|
||||||
|
|
||||||
|
var argIndex = 0;
|
||||||
|
if (objType == null && callExp.Method.DeclaringType.FullName == typeof(Enumerable).FullName) {
|
||||||
|
objExp = callExp.Arguments.FirstOrDefault();
|
||||||
|
objType = objExp?.Type;
|
||||||
|
argIndex++;
|
||||||
|
}
|
||||||
|
if (objType == null) objType = callExp.Method.DeclaringType;
|
||||||
|
if (objType != null) {
|
||||||
|
var left = objExp == null ? null : ExpressionLambdaToSql(objExp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
|
if (objType.IsArray == true) {
|
||||||
|
switch (callExp.Method.Name) {
|
||||||
|
case "Contains":
|
||||||
|
//判断 in
|
||||||
|
return $"({ExpressionLambdaToSql(callExp.Arguments[argIndex], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}) in {left}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ExpressionType.NewArrayInit:
|
||||||
|
var arrExp = exp as NewArrayExpression;
|
||||||
|
var arrSb = new StringBuilder();
|
||||||
|
arrSb.Append("(");
|
||||||
|
for (var a = 0; a < arrExp.Expressions.Count; a++) {
|
||||||
|
if (a > 0) arrSb.Append(",");
|
||||||
|
arrSb.Append(ExpressionLambdaToSql(arrExp.Expressions[a], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName));
|
||||||
|
}
|
||||||
|
return arrSb.Append(")").ToString();
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,46 +118,54 @@ namespace FreeSql.SqlServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
|
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||||
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
if (exp.Object == null) {
|
||||||
switch (exp.Method.Name) {
|
switch (exp.Method.Name) {
|
||||||
case "StartsWith":
|
case "IsNullOrEmpty":
|
||||||
case "EndsWith":
|
var arg1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
case "Contains":
|
return $"({arg1} is null or {arg1} = '')";
|
||||||
var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
}
|
||||||
if (args0Value == "NULL") return $"({left}) IS NULL";
|
} else {
|
||||||
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar)+'%')")}";
|
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar))")}";
|
switch (exp.Method.Name) {
|
||||||
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
|
case "StartsWith":
|
||||||
return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar)+'%')";
|
case "EndsWith":
|
||||||
case "ToLower": return $"lower({left})";
|
case "Contains":
|
||||||
case "ToUpper": return $"upper({left})";
|
var args0Value = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
case "Substring":
|
if (args0Value == "NULL") return $"({left}) IS NULL";
|
||||||
var substrArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar)+'%')")}";
|
||||||
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
|
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar))")}";
|
||||||
else substrArgs1 += "+1";
|
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
|
||||||
if (exp.Arguments.Count == 1) return $"left({left}, {substrArgs1})";
|
return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar)+'%')";
|
||||||
return $"substring({left}, {substrArgs1}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
case "ToLower": return $"lower({left})";
|
||||||
case "IndexOf":
|
case "ToUpper": return $"upper({left})";
|
||||||
var indexOfFindStr = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
case "Substring":
|
||||||
if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") {
|
var substrArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
var locateArgs1 = ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
|
||||||
if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString();
|
else substrArgs1 += "+1";
|
||||||
else locateArgs1 += "+1";
|
if (exp.Arguments.Count == 1) return $"left({left}, {substrArgs1})";
|
||||||
return $"(charindex({left}, {indexOfFindStr}, {locateArgs1})-1)";
|
return $"substring({left}, {substrArgs1}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
}
|
case "IndexOf":
|
||||||
return $"(charindex({left}, {indexOfFindStr})-1)";
|
var indexOfFindStr = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
case "PadLeft":
|
if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") {
|
||||||
if (exp.Arguments.Count == 1) return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
var locateArgs1 = ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString();
|
||||||
case "PadRight":
|
else locateArgs1 += "+1";
|
||||||
if (exp.Arguments.Count == 1) return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
return $"(charindex({left}, {indexOfFindStr}, {locateArgs1})-1)";
|
||||||
return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
}
|
||||||
case "Trim": return $"ltrim(rtrim({left}))";
|
return $"(charindex({left}, {indexOfFindStr})-1)";
|
||||||
case "TrimStart": return $"ltrim({left})";
|
case "PadLeft":
|
||||||
case "TrimEnd": return $"rtrim({left})";
|
if (exp.Arguments.Count == 1) return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
case "CompareTo": return $"({left} - {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
case "PadRight":
|
||||||
case "Equals": return $"({left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
if (exp.Arguments.Count == 1) return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
return $"rpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
case "Trim": return $"ltrim(rtrim({left}))";
|
||||||
|
case "TrimStart": return $"ltrim({left})";
|
||||||
|
case "TrimEnd": return $"rtrim({left})";
|
||||||
|
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
case "CompareTo": return $"({left} - {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
case "Equals": return $"({left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new Exception($"SqlServerExpression 未现实函数表达式 {exp} 解析");
|
throw new Exception($"SqlServerExpression 未现实函数表达式 {exp} 解析");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user