Skip to content

Commit

Permalink
in/not in
Browse files Browse the repository at this point in the history
  • Loading branch information
28810 authored and 28810 committed Dec 29, 2018
1 parent 43080a4 commit 96a944c
Show file tree
Hide file tree
Showing 13 changed files with 588 additions and 225 deletions.
39 changes: 36 additions & 3 deletions Docs/expression.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,54 @@
# 表达式函数
| 表达式 | 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 | 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 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 | 功能说明 |
| - | - | - | - | - |
| 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.Contains('b') | a like '%b%' | a like '%b%' | - | a是否包含b |
| a.EndsWith('b') | a like '%b' | a like '%b' | - | a尾部是否包含b |
Expand Down
92 changes: 92 additions & 0 deletions FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs
Original file line number Diff line number Diff line change
@@ -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 }
}
}
8 changes: 8 additions & 0 deletions FreeSql.Tests/MySql/MySqlExpression/StringTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -671,5 +671,13 @@ public void CompareTo() {
//FROM `tb_topic` a, `TestTypeInfo` a__Type
//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());
}
}
}
10 changes: 10 additions & 0 deletions FreeSql.Tests/PostgreSQL/PostgreSQLExpression/OtherTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ public void Array() {
var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).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 sql4 = select.Where(a => a.testFieldIntArray.Any() == false).ToList();

Expand Down
8 changes: 8 additions & 0 deletions FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -671,5 +671,13 @@ public void CompareTo() {
//FROM `tb_topic` a, `TestTypeInfo` a__Type
//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 changes: 88 additions & 0 deletions FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs
Original file line number Diff line number Diff line change
@@ -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 }
}
}
10 changes: 9 additions & 1 deletion FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,19 @@ public void CompareTo() {
//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 + 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(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.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());
}
}
}
1 change: 1 addition & 0 deletions FreeSql/Internal/CommonExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ internal void ExpressionJoinLambda(List<SelectTableInfo> _tables, SelectTableInf

internal string ExpressionLambdaToSql(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) {
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.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);
Expand Down
Loading

0 comments on commit 96a944c

Please sign in to comment.