mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
- 优化 Enum 位运算 MapType 解析;#1413
This commit is contained in:
parent
af44fdadb0
commit
f8773469bc
@ -800,14 +800,5 @@
|
|||||||
<param name="that"></param>
|
<param name="that"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
|
|
||||||
<summary>
|
|
||||||
批量注入 Repository,可以参考代码自行调整
|
|
||||||
</summary>
|
|
||||||
<param name="services"></param>
|
|
||||||
<param name="globalDataFilter"></param>
|
|
||||||
<param name="assemblies"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
</members>
|
</members>
|
||||||
</doc>
|
</doc>
|
||||||
|
@ -17,6 +17,80 @@ namespace FreeSql.Tests.MySqlExpression
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void BitEnum()
|
||||||
|
{
|
||||||
|
var fsql = g.mysql;
|
||||||
|
var sql1 = fsql.Select<BitEnum01>().Where(a => a.enum1 == TableAllTypeEnumType1.e5).ToSql();
|
||||||
|
var enum1 = TableAllTypeEnumType1.e5;
|
||||||
|
var sql2 = fsql.Select<BitEnum01>().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<BitEnum01>().Where(a => a.enum2 == TableAllTypeEnumType1.e5).ToSql();
|
||||||
|
sql2 = fsql.Select<BitEnum01>().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<BitEnum01>().Where(a => (a.enum1 & TableAllTypeEnumType1.e2) == TableAllTypeEnumType1.e2).ToSql();
|
||||||
|
enum1 = TableAllTypeEnumType1.e2;
|
||||||
|
sql2 = fsql.Select<BitEnum01>().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<BitEnum01>().Where(a => (a.enum2 & TableAllTypeEnumType1.e2) == TableAllTypeEnumType1.e2).ToSql();
|
||||||
|
enum1 = TableAllTypeEnumType1.e2;
|
||||||
|
sql2 = fsql.Select<BitEnum01>().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<BitEnum01>().Where(a => a.set1 == TableAllTypeEnumType2.f3).ToSql();
|
||||||
|
var set1 = TableAllTypeEnumType2.f3;
|
||||||
|
sql2 = fsql.Select<BitEnum01>().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<BitEnum01>().Where(a => a.set2 == TableAllTypeEnumType2.f3).ToSql();
|
||||||
|
sql2 = fsql.Select<BitEnum01>().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<BitEnum01>().Where(a => (a.set1 & TableAllTypeEnumType2.f2) == TableAllTypeEnumType2.f2).ToSql();
|
||||||
|
set1 = TableAllTypeEnumType2.f2;
|
||||||
|
sql2 = fsql.Select<BitEnum01>().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<BitEnum01>().Where(a => (a.set2 & TableAllTypeEnumType2.f2) == TableAllTypeEnumType2.f2).ToSql();
|
||||||
|
set1 = TableAllTypeEnumType2.f2;
|
||||||
|
sql2 = fsql.Select<BitEnum01>().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]
|
[Fact]
|
||||||
public void ArrayAnyOr()
|
public void ArrayAnyOr()
|
||||||
{
|
{
|
||||||
|
@ -2034,8 +2034,97 @@ namespace FreeSql.Internal
|
|||||||
if (exp.IsParameter() == false) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams);
|
if (exp.IsParameter() == false) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams);
|
||||||
return "";
|
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);
|
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 ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc);
|
||||||
public abstract string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc);
|
public abstract string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user