mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-09-21 02:58:05 +08:00
Update mongodb
This commit is contained in:
@@ -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>>();
|
||||||
|
@@ -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
|
||||||
@@ -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;
|
||||||
|
@@ -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)
|
||||||
|
Reference in New Issue
Block a user