Update mongodb

This commit is contained in:
sunkaixuan
2025-08-24 12:11:13 +08:00
parent 4deb4dc356
commit b3f02283cd
3 changed files with 151 additions and 26 deletions

View File

@@ -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;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
@@ -9,6 +12,46 @@ namespace SqlSugar.MongoDb
{ {
public class MongoDbExpTools public class MongoDbExpTools
{ {
/// <summary>
/// 将表达式转换成 FilterDefinition并返回对应的 BsonDocument
/// </summary>
public static BsonDocument GetFilterBson<TDocument>(Expression<Func<TDocument, bool>> predicate)
{
// 1. 构造 FilterDefinition
var filter = Builders<TDocument>.Filter.Where(predicate);
var serializer = BsonSerializer.SerializerRegistry.GetSerializer<TDocument>();
var registry = BsonSerializer.SerializerRegistry;
// 3. 构造 RenderArgs<TDocument>
var args = new RenderArgs<TDocument>(serializer, registry);
var bson = filter.Render(new RenderArgs<TDocument>(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<KeyValuePair<string, Expression>> ExtractIfElseEnd(MethodCallExpression expression) public static List<KeyValuePair<string, Expression>> ExtractIfElseEnd(MethodCallExpression expression)
{ {
var result = new List<KeyValuePair<string, Expression>>(); var result = new List<KeyValuePair<string, Expression>>();

View File

@@ -5,6 +5,10 @@ using System.Linq.Expressions;
using System.Text; using System.Text;
using System.Linq; 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 namespace SqlSugar.MongoDb
{ {
public class MethodCallExpressionTractor public class MethodCallExpressionTractor
@@ -30,7 +34,7 @@ namespace SqlSugar.MongoDb
BsonValue result = null; BsonValue result = null;
var context = new MongoDbMethod() { context = this._context }; var context = new MongoDbMethod() { context = this._context };
MethodCallExpressionModel model = new MethodCallExpressionModel(); MethodCallExpressionModel model = new MethodCallExpressionModel();
var args = methodCallExpression.Arguments; var args =methodCallExpression.Arguments;
model.Args = new List<MethodCallExpressionArgs>(); model.Args = new List<MethodCallExpressionArgs>();
model.DataObject = methodCallExpression.Object; model.DataObject = methodCallExpression.Object;
foreach (var item in args) foreach (var item in args)
@@ -130,9 +134,9 @@ namespace SqlSugar.MongoDb
{ {
return HandleSimpleValueListAny(methodCallExpression); return HandleSimpleValueListAny(methodCallExpression);
} }
else if (IsUnresolvableAnyExpression(anyArgModel)) else if (IsCallAnyExpression(anyArgModel))
{ {
return UnresolvablelexAnyExpression(methodCallExpression); return CallAnyExpression(methodCallExpression,anyArgModel);
} }
else else
{ {
@@ -161,18 +165,95 @@ namespace SqlSugar.MongoDb
result = bson; result = bson;
} }
} }
{
}
return result; 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) private BsonValue HandleSimpleValueListAny(MethodCallExpression methodCallExpression)
{ {
var memberExpression = methodCallExpression.Arguments[0] as MemberExpression; var memberExpression = methodCallExpression.Arguments[0] as MemberExpression;
@@ -351,17 +432,17 @@ namespace SqlSugar.MongoDb
{ {
var leftCount = ExpressionTool.GetParameters(MongoDbExpTools.RemoveConvert(b.Left)).Count(); var leftCount = ExpressionTool.GetParameters(MongoDbExpTools.RemoveConvert(b.Left)).Count();
var rightCount = ExpressionTool.GetParameters(MongoDbExpTools.RemoveConvert(b.Right)).Count(); var rightCount = ExpressionTool.GetParameters(MongoDbExpTools.RemoveConvert(b.Right)).Count();
if (leftCount != 1)
return false;
if (rightCount != 1)
return false;
anyArgModel.IsBinary = true;
anyArgModel.LamdaExpression = l; anyArgModel.LamdaExpression = l;
anyArgModel.Left = MongoDbExpTools.RemoveConvert(b.Left); anyArgModel.Left = MongoDbExpTools.RemoveConvert(b.Left);
anyArgModel.LeftCount = leftCount; anyArgModel.LeftCount = leftCount;
anyArgModel.RightCount = rightCount; anyArgModel.RightCount = rightCount;
anyArgModel.Right = MongoDbExpTools.RemoveConvert(b.Right); anyArgModel.Right = MongoDbExpTools.RemoveConvert(b.Right);
anyArgModel.NodeType = b.NodeType; anyArgModel.NodeType = b.NodeType;
if (leftCount != 1)
return false;
if (rightCount != 1)
return false;
anyArgModel.IsBinary = true;
} }
return true; return true;
} }
@@ -499,16 +580,15 @@ namespace SqlSugar.MongoDb
return name; return name;
} }
private bool IsUnresolvableAnyExpression(AnyArgModel anyArgModel) private bool IsCallAnyExpression(AnyArgModel anyArgModel)
{ {
var leftIsUn = !(anyArgModel.Left is MemberExpression) && anyArgModel.LeftCount >= 1; var isleftCall = (anyArgModel.Left is MethodCallExpression) && anyArgModel.LeftCount >= 1;
var rightIsUn = !(anyArgModel.Right is MemberExpression) && anyArgModel.RightCount >= 1; var isRightCall = !(anyArgModel.Right is MethodCallExpression) && anyArgModel.RightCount >= 1;
if (anyArgModel.Right is BinaryExpression rb|| anyArgModel.Left is BinaryExpression lb) var allCount = anyArgModel.LeftCount + anyArgModel.RightCount;
{ if ((isleftCall || isRightCall) && allCount == 1&&anyArgModel.NodeType.IsIn(ExpressionType.Equal,ExpressionType.NotEqual))
return false;
}
if (leftIsUn|| rightIsUn)
{ {
anyArgModel.Left = isleftCall? anyArgModel.Left:anyArgModel.Right;
anyArgModel.Right = isleftCall ? anyArgModel.Right: anyArgModel.Left;
return true; return true;
} }
return false; return false;

View File

@@ -483,6 +483,8 @@ namespace SqlSugar.MongoDb
public override string ToString(MethodCallExpressionModel model) public override string ToString(MethodCallExpressionModel model)
{ {
var item = model.DataObject as Expression; 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); BsonValue memberName = new ExpressionVisitor(context).Visit(item as Expression);
if (model.Args == null || model.Args.Count == 0) if (model.Args == null || model.Args.Count == 0)