diff --git a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/MongoDbExpTools.cs b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/MongoDbExpTools.cs
index af65fb512..d202b1588 100644
--- a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/MongoDbExpTools.cs
+++ b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/MongoDbExpTools.cs
@@ -1,4 +1,7 @@
-using MongoDB.Bson;
+using MongoDb.Ado.data;
+using MongoDB.Bson;
+using MongoDB.Bson.Serialization;
+using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -9,6 +12,46 @@ namespace SqlSugar.MongoDb
{
public class MongoDbExpTools
{
+ ///
+ /// 将表达式转换成 FilterDefinition,并返回对应的 BsonDocument
+ ///
+ public static BsonDocument GetFilterBson(Expression> predicate)
+ {
+ // 1. 构造 FilterDefinition
+ var filter = Builders.Filter.Where(predicate);
+ var serializer = BsonSerializer.SerializerRegistry.GetSerializer();
+ var registry = BsonSerializer.SerializerRegistry;
+
+ // 3. 构造 RenderArgs
+ var args = new RenderArgs(serializer, registry);
+
+ var bson = filter.Render(new RenderArgs(serializer, registry));
+ return bson;
+ }
+ public static Expression GetRootObject(Expression expr)
+ {
+ while (true)
+ {
+ switch (expr)
+ {
+ case MemberExpression memberExpr:
+ expr = memberExpr.Expression;
+ break;
+
+ case MethodCallExpression methodCallExpr:
+ expr = methodCallExpr.Object ??
+ (methodCallExpr.Arguments.Count > 0 ? methodCallExpr.Arguments[0] : null);
+ break;
+
+ case UnaryExpression unaryExpr:
+ expr = unaryExpr.Operand;
+ break;
+
+ default:
+ return expr;
+ }
+ }
+ }
public static List> ExtractIfElseEnd(MethodCallExpression expression)
{
var result = new List>();
diff --git a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/MethodCallExpressionTractor.cs b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/MethodCallExpressionTractor.cs
index f9ef39c7a..ec4788a1f 100644
--- a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/MethodCallExpressionTractor.cs
+++ b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/MethodCallExpressionTractor.cs
@@ -4,7 +4,11 @@ using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Linq;
-using System.Collections;
+using System.Collections;
+using System.Reflection;
+using MongoDB.Driver;
+using MongoDB.Bson.Serialization;
+using System.Diagnostics.CodeAnalysis;
namespace SqlSugar.MongoDb
{
public class MethodCallExpressionTractor
@@ -30,7 +34,7 @@ namespace SqlSugar.MongoDb
BsonValue result = null;
var context = new MongoDbMethod() { context = this._context };
MethodCallExpressionModel model = new MethodCallExpressionModel();
- var args = methodCallExpression.Arguments;
+ var args =methodCallExpression.Arguments;
model.Args = new List();
model.DataObject = methodCallExpression.Object;
foreach (var item in args)
@@ -130,9 +134,9 @@ namespace SqlSugar.MongoDb
{
return HandleSimpleValueListAny(methodCallExpression);
}
- else if (IsUnresolvableAnyExpression(anyArgModel))
+ else if (IsCallAnyExpression(anyArgModel))
{
- return UnresolvablelexAnyExpression(methodCallExpression);
+ return CallAnyExpression(methodCallExpression,anyArgModel);
}
else
{
@@ -160,19 +164,96 @@ namespace SqlSugar.MongoDb
};
result = bson;
}
- }
- {
- }
+ }
return result;
}
}
- private BsonValue UnresolvablelexAnyExpression(MethodCallExpression methodCallExpression)
+ private BsonValue CallAnyExpression(MethodCallExpression methodCall, AnyArgModel anyArgModel)
{
- BsonValue bsonValue = null;
- return null;
- }
+ // 获取集合字段名
+ var collectionField = MongoNestedTranslator.TranslateNoFieldName(
+ methodCall.Arguments[0],
+ _context,
+ new ExpressionVisitorContext { IsText = true }
+ )?.ToString();
+ var leftExpr = anyArgModel.Left as MethodCallExpression;
+ var rightExpr = anyArgModel.Right;
+
+ // 处理左边表达式(如 $toString: "$$b.Age")
+ BsonValue leftValue;
+ if (leftExpr != null)
+ {
+ leftValue = MongoNestedTranslator.TranslateNoFieldName(
+ leftExpr,
+ _context,
+ new ExpressionVisitorContext { IsText = true }
+ );
+ }
+ else
+ {
+ leftValue = MongoNestedTranslator.TranslateNoFieldName(
+ anyArgModel.Left,
+ _context,
+ new ExpressionVisitorContext { IsText = true }
+ );
+ }
+
+ // 处理右边表达式(如常量 "99")
+ BsonValue rightValue;
+ if (rightExpr is ConstantExpression constantExpr)
+ {
+ rightValue = UtilMethods.MyCreate(constantExpr.Value);
+ }
+ else
+ {
+ rightValue = MongoNestedTranslator.TranslateNoFieldName(
+ rightExpr,
+ _context,
+ new ExpressionVisitorContext { IsText = true }
+ );
+ }
+
+ // 构造 $map
+ var mapDoc = new BsonDocument
+ {
+ { "input", $"${collectionField}" },
+ { "as", "b" },
+ { "in", leftValue }
+ };
+
+ // 构造 $expr/$in
+ var exprDoc = new BsonDocument
+ {
+ { "$in", new BsonArray { rightValue, new BsonDocument("$map", mapDoc) } }
+ };
+
+ var bson = new BsonDocument
+ {
+ { "$expr", exprDoc }
+ };
+
+ return bson;
+ }
+ public static BsonValue TranslateMethodCall(MethodCallExpression methodCall, Type documentType,string name)
+ {
+ var type = typeof(MongoDbExpTools);
+
+ // 获取泛型方法定义
+ var method = type.GetMethod("GetFilterBson", BindingFlags.Public | BindingFlags.Static);
+ if (method == null)
+ throw new InvalidOperationException("找不到 GetFilterBson 方法");
+
+ // 构造泛型方法
+ var genericMethod = method.MakeGenericMethod(documentType);
+
+ // 调用方法 (假设 methodCall 就是 Expression)
+ var lambda = Expression.Lambda(methodCall, ExpressionTool.GetParameters(methodCall).First());
+ var result = genericMethod.Invoke(null, new object[] { lambda });
+
+ return (BsonValue)result;
+ }
private BsonValue HandleSimpleValueListAny(MethodCallExpression methodCallExpression)
{
var memberExpression = methodCallExpression.Arguments[0] as MemberExpression;
@@ -350,18 +431,18 @@ namespace SqlSugar.MongoDb
if (methodCallExpression.Arguments[1] is LambdaExpression l&&l.Body is BinaryExpression b)
{
var leftCount = ExpressionTool.GetParameters(MongoDbExpTools.RemoveConvert(b.Left)).Count();
- var rightCount = ExpressionTool.GetParameters(MongoDbExpTools.RemoveConvert(b.Right)).Count();
- if (leftCount != 1)
- return false;
- if (rightCount != 1)
- return false;
- anyArgModel.IsBinary = true;
+ var rightCount = ExpressionTool.GetParameters(MongoDbExpTools.RemoveConvert(b.Right)).Count();
anyArgModel.LamdaExpression = l;
anyArgModel.Left = MongoDbExpTools.RemoveConvert(b.Left);
anyArgModel.LeftCount = leftCount;
anyArgModel.RightCount = rightCount;
anyArgModel.Right = MongoDbExpTools.RemoveConvert(b.Right);
anyArgModel.NodeType = b.NodeType;
+ if (leftCount != 1)
+ return false;
+ if (rightCount != 1)
+ return false;
+ anyArgModel.IsBinary = true;
}
return true;
}
@@ -499,16 +580,15 @@ namespace SqlSugar.MongoDb
return name;
}
- private bool IsUnresolvableAnyExpression(AnyArgModel anyArgModel)
+ private bool IsCallAnyExpression(AnyArgModel anyArgModel)
{
- var leftIsUn = !(anyArgModel.Left is MemberExpression) && anyArgModel.LeftCount >= 1;
- var rightIsUn = !(anyArgModel.Right is MemberExpression) && anyArgModel.RightCount >= 1;
- if (anyArgModel.Right is BinaryExpression rb|| anyArgModel.Left is BinaryExpression lb)
- {
- return false;
- }
- if (leftIsUn|| rightIsUn)
+ var isleftCall = (anyArgModel.Left is MethodCallExpression) && anyArgModel.LeftCount >= 1;
+ var isRightCall = !(anyArgModel.Right is MethodCallExpression) && anyArgModel.RightCount >= 1;
+ var allCount = anyArgModel.LeftCount + anyArgModel.RightCount;
+ if ((isleftCall || isRightCall) && allCount == 1&&anyArgModel.NodeType.IsIn(ExpressionType.Equal,ExpressionType.NotEqual))
{
+ anyArgModel.Left = isleftCall? anyArgModel.Left:anyArgModel.Right;
+ anyArgModel.Right = isleftCall ? anyArgModel.Right: anyArgModel.Left;
return true;
}
return false;
diff --git a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/MongoDb/SqlBuilder/MongoDbExpressionContext.cs b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/MongoDb/SqlBuilder/MongoDbExpressionContext.cs
index 2f041ef5c..b1f866a98 100644
--- a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/MongoDb/SqlBuilder/MongoDbExpressionContext.cs
+++ b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/MongoDb/SqlBuilder/MongoDbExpressionContext.cs
@@ -483,6 +483,8 @@ namespace SqlSugar.MongoDb
public override string ToString(MethodCallExpressionModel model)
{
var item = model.DataObject as Expression;
+ if (item == null && model.Args.Any())
+ item = model.Args[0].MemberValue as Expression;
BsonValue memberName = new ExpressionVisitor(context).Visit(item as Expression);
if (model.Args == null || model.Args.Count == 0)