- 优化 兼容不同数据库 bool 的表达式解析

This commit is contained in:
28810 2019-04-27 15:59:03 +08:00
parent 74a2cf5317
commit 43d966cc90
7 changed files with 109 additions and 12 deletions

View File

@ -14,6 +14,20 @@ namespace FreeSql.Tests.MySqlExpression {
} }
[Fact]
public void Boolean() {
var t1 = select.Where(a => a.testFieldBool == true).ToList();
var t2 = select.Where(a => a.testFieldBool != true).ToList();
var t3 = select.Where(a => a.testFieldBool == false).ToList();
var t4 = select.Where(a => !a.testFieldBool).ToList();
var t5 = select.Where(a => a.testFieldBool).ToList();
var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList();
var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList();
var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList();
var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList();
var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList();
}
[Fact] [Fact]
public void Array() { public void Array() {

View File

@ -12,6 +12,20 @@ namespace FreeSql.Tests.OracleExpression {
public OtherTest() { public OtherTest() {
} }
[Fact]
public void Boolean() {
var t1 = select.Where(a => a.Bool == true).ToList();
var t2 = select.Where(a => a.Bool != true).ToList();
var t3 = select.Where(a => a.Bool == false).ToList();
var t4 = select.Where(a => !a.Bool).ToList();
var t5 = select.Where(a => a.Bool).ToList();
var t11 = select.Where(a => a.BoolNullable == true).ToList();
var t22 = select.Where(a => a.BoolNullable != true).ToList();
var t33 = select.Where(a => a.BoolNullable == false).ToList();
var t44 = select.Where(a => !a.BoolNullable.Value).ToList();
var t55 = select.Where(a => a.BoolNullable.Value).ToList();
}
[Fact] [Fact]
public void Array() { public void Array() {

View File

@ -20,6 +20,20 @@ namespace FreeSql.Tests.PostgreSQLExpression {
NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis(); NpgsqlConnection.GlobalTypeMapper.UseLegacyPostgis();
} }
[Fact]
public void Boolean() {
var t1 = select.Where(a => a.testFieldBool == true).ToList();
var t2 = select.Where(a => a.testFieldBool != true).ToList();
var t3 = select.Where(a => a.testFieldBool == false).ToList();
var t4 = select.Where(a => !a.testFieldBool).ToList();
var t5 = select.Where(a => a.testFieldBool).ToList();
var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList();
var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList();
var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList();
var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList();
var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList();
}
[Fact] [Fact]
public void Array() { public void Array() {

View File

@ -18,6 +18,21 @@ namespace FreeSql.Tests.SqlServerExpression {
ISelect<TableAllType> select => _sqlserverFixture.SqlServer.Select<TableAllType>(); ISelect<TableAllType> select => _sqlserverFixture.SqlServer.Select<TableAllType>();
[Fact]
public void Boolean() {
var t1 = select.Where(a => a.testFieldBool == true).ToList();
var t2 = select.Where(a => a.testFieldBool != true).ToList();
var t3 = select.Where(a => a.testFieldBool == false).ToList();
var t4 = select.Where(a => !a.testFieldBool).ToList();
var t5 = select.Where(a => a.testFieldBool).ToList();
var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList();
var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList();
var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList();
var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList();
var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList();
}
[Fact] [Fact]
public void Array() { public void Array() {
IEnumerable<int> testlinqlist = new List<int>(new[] { 1, 2, 3 }); IEnumerable<int> testlinqlist = new List<int>(new[] { 1, 2, 3 });
@ -25,26 +40,26 @@ namespace FreeSql.Tests.SqlServerExpression {
//in not in //in not in
var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
//var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList();
var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
var inarray = new[] { 1, 2, 3 }; var inarray = new[] { 1, 2, 3 };
var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList();
//var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList();
var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList();
//in not in //in not in
var sql11111 = select.Where(a => new List<int>() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); var sql11111 = select.Where(a => new List<int>() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
//var sql11222 = select.Where(a => new List<int>() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); var sql11222 = select.Where(a => new List<int>() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList();
var sql11333 = select.Where(a => !new List<int>() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); var sql11333 = select.Where(a => !new List<int>() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
var sql11111a = select.Where(a => new List<int>(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); var sql11111a = select.Where(a => new List<int>(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList();
//var sql11222b = select.Where(a => new List<int>(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); var sql11222b = select.Where(a => new List<int>(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList();
var sql11333c = select.Where(a => !new List<int>(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); var sql11333c = select.Where(a => !new List<int>(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList();
var inarray2 = new List<int>() { 1, 2, 3 }; var inarray2 = new List<int>() { 1, 2, 3 };
var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList();
//var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList();
var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList();
} }

View File

@ -12,6 +12,20 @@ namespace FreeSql.Tests.SqliteExpression {
public OtherTest() { public OtherTest() {
} }
[Fact]
public void Boolean() {
var t1 = select.Where(a => a.Bool == true).ToList();
var t2 = select.Where(a => a.Bool != true).ToList();
var t3 = select.Where(a => a.Bool == false).ToList();
var t4 = select.Where(a => !a.Bool).ToList();
var t5 = select.Where(a => a.Bool).ToList();
var t11 = select.Where(a => a.BoolNullable == true).ToList();
var t22 = select.Where(a => a.BoolNullable != true).ToList();
var t33 = select.Where(a => a.BoolNullable == false).ToList();
var t44 = select.Where(a => !a.BoolNullable.Value).ToList();
var t55 = select.Where(a => a.BoolNullable.Value).ToList();
}
[Fact] [Fact]
public void Array() { public void Array() {
@ -20,26 +34,26 @@ namespace FreeSql.Tests.SqliteExpression {
//in not in //in not in
var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList();
//var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList();
var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList();
var inarray = new[] { 1, 2, 3 }; var inarray = new[] { 1, 2, 3 };
var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList();
//var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList();
var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList();
//in not in //in not in
var sql11111 = select.Where(a => new List<int>() { 1, 2, 3 }.Contains(a.Int)).ToList(); var sql11111 = select.Where(a => new List<int>() { 1, 2, 3 }.Contains(a.Int)).ToList();
//var sql11222 = select.Where(a => new List<int>() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); var sql11222 = select.Where(a => new List<int>() { 1, 2, 3 }.Contains(a.Int) == false).ToList();
var sql11333 = select.Where(a => !new List<int>() { 1, 2, 3 }.Contains(a.Int)).ToList(); var sql11333 = select.Where(a => !new List<int>() { 1, 2, 3 }.Contains(a.Int)).ToList();
var sql11111a = select.Where(a => new List<int>(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); var sql11111a = select.Where(a => new List<int>(new[] { 1, 2, 3 }).Contains(a.Int)).ToList();
//var sql11222b = select.Where(a => new List<int>(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); var sql11222b = select.Where(a => new List<int>(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList();
var sql11333c = select.Where(a => !new List<int>(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); var sql11333c = select.Where(a => !new List<int>(new[] { 1, 2, 3 }).Contains(a.Int)).ToList();
var inarray2 = new List<int>() { 1, 2, 3 }; var inarray2 = new List<int>() { 1, 2, 3 };
var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList();
//var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList();
var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList();
} }

View File

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

View File

@ -278,6 +278,8 @@ namespace FreeSql.Internal {
}; };
internal string ExpressionWhereLambdaNoneForeignObject(List<SelectTableInfo> _tables, TableInfo table, List<SelectColumnInfo> _selectColumnMap, Expression exp, Func<Expression[], string> getSelectGroupingMapString) { internal string ExpressionWhereLambdaNoneForeignObject(List<SelectTableInfo> _tables, TableInfo table, List<SelectColumnInfo> _selectColumnMap, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table }); var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table });
if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool))
return $"{sql} = {formatSql(true, null)}";
switch (sql) { switch (sql) {
case "1": case "1":
case "'t'": return "1=1"; case "'t'": return "1=1";
@ -289,6 +291,8 @@ namespace FreeSql.Internal {
internal string ExpressionWhereLambda(List<SelectTableInfo> _tables, Expression exp, Func<Expression[], string> getSelectGroupingMapString) { internal string ExpressionWhereLambda(List<SelectTableInfo> _tables, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }); var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where });
if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool))
return $"{sql} = {formatSql(true, null)}";
switch (sql) { switch (sql) {
case "1": case "1":
case "'t'": return "1=1"; case "'t'": return "1=1";
@ -300,6 +304,8 @@ namespace FreeSql.Internal {
internal void ExpressionJoinLambda(List<SelectTableInfo> _tables, SelectTableInfoType tbtype, Expression exp, Func<Expression[], string> getSelectGroupingMapString) { internal void ExpressionJoinLambda(List<SelectTableInfo> _tables, SelectTableInfoType tbtype, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
var tbidx = _tables.Count; var tbidx = _tables.Count;
var filter = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where }); var filter = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where });
if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool))
filter = $"{filter} = {formatSql(true, null)}";
switch (filter) { switch (filter) {
case "1": case "1":
case "'t'": filter = "1=1"; break; case "'t'": filter = "1=1"; break;
@ -354,6 +360,23 @@ namespace FreeSql.Internal {
} }
} }
} }
if (leftExp.Type.NullableTypeOrThis() == typeof(bool) && (leftExp.NodeType != ExpressionType.MemberAccess && rightExp.NodeType != ExpressionType.MemberAccess)) {
if (oper == "=") {
var trueVal = formatSql(true, null);
var falseVal = formatSql(false, null);
if (left == trueVal) return right;
else if (left == falseVal) return $"not({right})";
else if (right == trueVal) return left;
else if (right == falseVal) return $"not({left})";
} else if (oper == "<>") {
var trueVal = formatSql(true, null);
var falseVal = formatSql(false, null);
if (left == trueVal) return $"not({right})";
else if (left == falseVal) return right;
else if (right == trueVal) return $"not({left})";
else if (right == falseVal) return left;
}
}
if (left == "NULL") { if (left == "NULL") {
var tmp = right; var tmp = right;
@ -374,7 +397,10 @@ namespace FreeSql.Internal {
if (string.IsNullOrEmpty(args.Result) == false) return args.Result; if (string.IsNullOrEmpty(args.Result) == false) return args.Result;
} }
switch (exp.NodeType) { switch (exp.NodeType) {
case ExpressionType.Not: return $"not({ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc)})"; case ExpressionType.Not:
var notExp = (exp as UnaryExpression)?.Operand;
if (notExp.NodeType == ExpressionType.MemberAccess) return $"{ExpressionLambdaToSql(notExp, tsc)} = {formatSql(false, null)}";
return $"not({ExpressionLambdaToSql(notExp, tsc)})";
case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc);
case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, tsc); case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, tsc);
case ExpressionType.TypeAs: case ExpressionType.TypeAs: