From f8773469bc261fd43e2b9c53a25b24aa1b88404f Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Wed, 8 Feb 2023 19:35:19 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20Enum=20=E4=BD=8D?= =?UTF-8?q?=E8=BF=90=E7=AE=97=20MapType=20=E8=A7=A3=E6=9E=90=EF=BC=9B#1413?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 -- .../MySql/MySqlExpression/OtherTest.cs | 74 +++++++++++++++ FreeSql/Internal/CommonExpression.cs | 89 +++++++++++++++++++ 3 files changed, 163 insertions(+), 9 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 26522f10..537315e2 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -800,14 +800,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs index 81a1d05a..03a195d7 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/OtherTest.cs @@ -17,6 +17,80 @@ namespace FreeSql.Tests.MySqlExpression } + [Fact] + public void BitEnum() + { + var fsql = g.mysql; + var sql1 = fsql.Select().Where(a => a.enum1 == TableAllTypeEnumType1.e5).ToSql(); + var enum1 = TableAllTypeEnumType1.e5; + var sql2 = fsql.Select().Where(a => a.enum1 == enum1).ToSql(); + Assert.Equal(sql1, sql2); + Assert.Equal(@"SELECT a.`id`, a.`enum1`, a.`enum2`, a.`set1`, a.`set2` +FROM `BitEnum01` a +WHERE (a.`enum1` = 'e5')", sql1); + sql1 = fsql.Select().Where(a => a.enum2 == TableAllTypeEnumType1.e5).ToSql(); + sql2 = fsql.Select().Where(a => a.enum2 == enum1).ToSql(); + Assert.Equal(sql1, sql2); + Assert.Equal(@"SELECT a.`id`, a.`enum1`, a.`enum2`, a.`set1`, a.`set2` +FROM `BitEnum01` a +WHERE (a.`enum2` = 3)", sql1); + + sql1 = fsql.Select().Where(a => (a.enum1 & TableAllTypeEnumType1.e2) == TableAllTypeEnumType1.e2).ToSql(); + enum1 = TableAllTypeEnumType1.e2; + sql2 = fsql.Select().Where(a => (a.enum1 & enum1) == enum1).ToSql(); + Assert.Equal(sql1, sql2); + Assert.Equal(@"SELECT a.`id`, a.`enum1`, a.`enum2`, a.`set1`, a.`set2` +FROM `BitEnum01` a +WHERE ((a.`enum1` & 'e2') = 'e2')", sql1); + sql1 = fsql.Select().Where(a => (a.enum2 & TableAllTypeEnumType1.e2) == TableAllTypeEnumType1.e2).ToSql(); + enum1 = TableAllTypeEnumType1.e2; + sql2 = fsql.Select().Where(a => (a.enum2 & enum1) == enum1).ToSql(); + Assert.Equal(sql1, sql2); + Assert.Equal(@"SELECT a.`id`, a.`enum1`, a.`enum2`, a.`set1`, a.`set2` +FROM `BitEnum01` a +WHERE ((a.`enum2` & 1) = 1)", sql1); + + + sql1 = fsql.Select().Where(a => a.set1 == TableAllTypeEnumType2.f3).ToSql(); + var set1 = TableAllTypeEnumType2.f3; + sql2 = fsql.Select().Where(a => a.set1 == set1).ToSql(); + Assert.Equal(sql1, sql2); + Assert.Equal(@"SELECT a.`id`, a.`enum1`, a.`enum2`, a.`set1`, a.`set2` +FROM `BitEnum01` a +WHERE (a.`set1` = 'f3')", sql1); + sql1 = fsql.Select().Where(a => a.set2 == TableAllTypeEnumType2.f3).ToSql(); + sql2 = fsql.Select().Where(a => a.set2 == set1).ToSql(); + Assert.Equal(sql1, sql2); + Assert.Equal(@"SELECT a.`id`, a.`enum1`, a.`enum2`, a.`set1`, a.`set2` +FROM `BitEnum01` a +WHERE (a.`set2` = 2)", sql1); + + sql1 = fsql.Select().Where(a => (a.set1 & TableAllTypeEnumType2.f2) == TableAllTypeEnumType2.f2).ToSql(); + set1 = TableAllTypeEnumType2.f2; + sql2 = fsql.Select().Where(a => (a.set1 & set1) == set1).ToSql(); + Assert.Equal(sql1, sql2); + Assert.Equal(@"SELECT a.`id`, a.`enum1`, a.`enum2`, a.`set1`, a.`set2` +FROM `BitEnum01` a +WHERE ((a.`set1` & 'f2') = 'f2')", sql1); + sql1 = fsql.Select().Where(a => (a.set2 & TableAllTypeEnumType2.f2) == TableAllTypeEnumType2.f2).ToSql(); + set1 = TableAllTypeEnumType2.f2; + sql2 = fsql.Select().Where(a => (a.set2 & set1) == set1).ToSql(); + Assert.Equal(sql1, sql2); + Assert.Equal(@"SELECT a.`id`, a.`enum1`, a.`enum2`, a.`set1`, a.`set2` +FROM `BitEnum01` a +WHERE ((a.`set2` & 1) = 1)", sql1); + } + class BitEnum01 + { + public int id { get; set; } + public TableAllTypeEnumType1 enum1 { get; set; } + [Column(MapType = typeof(int))] + public TableAllTypeEnumType1 enum2 { get; set; } + public TableAllTypeEnumType2 set1 { get; set; } + [Column(MapType = typeof(long))] + public TableAllTypeEnumType2 set2 { get; set; } + } + [Fact] public void ArrayAnyOr() { diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 877af3e5..af38d602 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -2034,8 +2034,97 @@ namespace FreeSql.Internal if (exp.IsParameter() == false) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); return ""; } + switch (expBinary.NodeType) + { + case ExpressionType.Equal: + case ExpressionType.NotEqual: + //位运算 + MapType + var bitwiseResult = ExpressionBinaryBitwise(tryoper, expBinary.Left, expBinary.Right, tsc); + if (string.IsNullOrEmpty(bitwiseResult) == false) return bitwiseResult; + break; + } return ExpressionBinary(tryoper, expBinary.Left, expBinary.Right, tsc); } + public string ExpressionBinaryBitwise(string oper, Expression leftExp, Expression rightExp, ExpTSC tsc) + { + string LocalSwithBitResult(Expression expBit, string r1, string r2) + { + switch (expBit.NodeType) + { + case ExpressionType.And: return _common.BitAnd(r1, r2); + case ExpressionType.Or: return _common.BitOr(r1, r2); + case ExpressionType.LeftShift: return _common.BitShiftLeft(r1, r2); + case ExpressionType.RightShift: return _common.BitShiftRight(r1, r2); + case ExpressionType.ExclusiveOr: return _common.BitXor(r1, r2); + } + return ""; + } + while (leftExp.NodeType == ExpressionType.Convert && leftExp is UnaryExpression leftExpUExp) leftExp = leftExpUExp.Operand; + switch (leftExp.NodeType) + { + case ExpressionType.And: + case ExpressionType.Or: + case ExpressionType.LeftShift: + case ExpressionType.RightShift: + case ExpressionType.ExclusiveOr: + var leftBinary = leftExp as BinaryExpression; + var leftBinaryL = ExpressionLambdaToSql(leftBinary.Left, tsc); + var leftBinaryR = ""; + var leftBinaryColumn = SearchColumnByField(tsc._tables, tsc.currentTable, leftBinaryL); + if (leftBinaryColumn != null) + { + var oldMapType = tsc.SetMapTypeReturnOld(leftBinaryColumn.Attribute.MapType); + leftBinaryR = ExpressionLambdaToSql(leftBinary.Right, tsc); + var rightResult = ExpressionLambdaToSql(rightExp, tsc); + tsc.SetMapTypeReturnOld(oldMapType); + return $"{LocalSwithBitResult(leftExp, leftBinaryL, leftBinaryR)} {oper} {rightResult}"; + } + leftBinaryR = ExpressionLambdaToSql(leftBinary.Right, tsc); + leftBinaryColumn = SearchColumnByField(tsc._tables, tsc.currentTable, leftBinaryR); + if (leftBinaryColumn != null) + { + var oldMapType = tsc.SetMapTypeReturnOld(leftBinaryColumn.Attribute.MapType); + leftBinaryL = ExpressionLambdaToSql(leftBinary.Left, tsc); + var rightResult = ExpressionLambdaToSql(rightExp, tsc); + tsc.SetMapTypeReturnOld(oldMapType); + return $"{LocalSwithBitResult(leftExp, leftBinaryL, leftBinaryR)} {oper} {rightResult}"; + } + break; + } + while (rightExp.NodeType == ExpressionType.Convert && rightExp is UnaryExpression rightExpUExp) rightExp = rightExpUExp.Operand; + switch (rightExp.NodeType) + { + case ExpressionType.And: + case ExpressionType.Or: + case ExpressionType.LeftShift: + case ExpressionType.RightShift: + case ExpressionType.ExclusiveOr: + var rightBinary = rightExp as BinaryExpression; + var rightBinaryL = ExpressionLambdaToSql(rightBinary.Left, tsc); + var rightBinaryR = ""; + var rightBinaryColumn = SearchColumnByField(tsc._tables, tsc.currentTable, rightBinaryL); + if (rightBinaryColumn != null) + { + var oldMapType = tsc.SetMapTypeReturnOld(rightBinaryColumn.Attribute.MapType); + rightBinaryR = ExpressionLambdaToSql(rightBinary.Right, tsc); + var leftResult = ExpressionLambdaToSql(leftExp, tsc); + tsc.SetMapTypeReturnOld(oldMapType); + return $"{leftResult} {oper} {LocalSwithBitResult(rightExp, rightBinaryL, rightBinaryR)}"; + } + rightBinaryR = ExpressionLambdaToSql(rightBinary.Right, tsc); + rightBinaryColumn = SearchColumnByField(tsc._tables, tsc.currentTable, rightBinaryR); + if (rightBinaryColumn != null) + { + var oldMapType = tsc.SetMapTypeReturnOld(rightBinaryColumn.Attribute.MapType); + rightBinaryL = ExpressionLambdaToSql(rightBinary.Left, tsc); + var leftResult = ExpressionLambdaToSql(leftExp, tsc); + tsc.SetMapTypeReturnOld(oldMapType); + return $"{leftResult} {oper} {LocalSwithBitResult(rightExp, rightBinaryL, rightBinaryR)}"; + } + break; + } + return ""; + } public abstract string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc); public abstract string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc);