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);