Update Mongodb

This commit is contained in:
sunkaixuan 2025-05-04 21:09:25 +08:00
parent 03cb3ee32b
commit f45f9975d8
5 changed files with 67 additions and 57 deletions

View File

@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq;
using MongoDB.Bson;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
@ -9,20 +10,23 @@ namespace SqlSugar.MongoDbCore
public class ExpressionVisitor
{
private MongoNestedTranslatorContext context;
public ExpressionVisitorContext visitorContext;
public ExpressionVisitorContext visitorContext;
public ExpressionVisitor(MongoNestedTranslatorContext context, ExpressionVisitorContext expressionVisitorContext)
{
this.context = context;
this.visitorContext = expressionVisitorContext;
}
public ExpressionVisitor(MongoNestedTranslatorContext context)
{
this.context = context;
}
public JToken Visit(Expression expr)
public BsonValue Visit(Expression expr)
{
expr = MongoDbExpTools.RemoveConvert(expr);
switch (expr)
{
case BinaryExpression binary:
@ -34,7 +38,7 @@ namespace SqlSugar.MongoDbCore
case UnaryExpression unary:
return this.Visit(unary);
case LambdaExpression lambda:
return this.Visit((lambda as LambdaExpression).Body);
return this.Visit(lambda.Body);
default:
throw new NotSupportedException($"Unsupported expression: {expr.NodeType}");
}

View File

@ -2,16 +2,16 @@
using System.Collections.Generic;
using System.Text;
using System.Linq.Expressions;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq;
using MongoDB.Bson;
namespace SqlSugar.MongoDbCore
{
{
public static class MongoNestedTranslator
{
public static JObject Translate(Expression expr, MongoNestedTranslatorContext context)
public static BsonDocument Translate(Expression expr, MongoNestedTranslatorContext context)
{
return (JObject)new ExpressionVisitor(context).Visit(expr);
}
}
return (BsonDocument)new ExpressionVisitor(context).Visit(expr);
}
}
}

View File

@ -1,4 +1,5 @@
using MongoDB.Driver;
using MongoDB.Bson;
using MongoDB.Driver;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
@ -7,7 +8,7 @@ using System.Text;
namespace SqlSugar.MongoDbCore
{
public class BinaryExpressionTranslator
public class BinaryExpressionTranslator
{
MongoNestedTranslatorContext _context;
@ -16,7 +17,7 @@ namespace SqlSugar.MongoDbCore
_context = context;
}
public JToken Extract(BinaryExpression expr)
public BsonDocument Extract(BinaryExpression expr)
{
if (expr.NodeType == ExpressionType.AndAlso || expr.NodeType == ExpressionType.OrElse)
{
@ -26,25 +27,26 @@ namespace SqlSugar.MongoDbCore
return FieldComparisonExpression(expr);
}
private JToken LogicalBinaryExpression(BinaryExpression expr)
private BsonDocument LogicalBinaryExpression(BinaryExpression expr)
{
string logicOp = expr.NodeType == ExpressionType.AndAlso ? "$and" : "$or";
var left = new ExpressionVisitor(_context).Visit(expr.Left);
var right =new ExpressionVisitor(_context).Visit(expr.Right);
var right = new ExpressionVisitor(_context).Visit(expr.Right);
var arr = new JArray();
var arr = new BsonArray();
AddNestedLogic(arr, left, logicOp);
AddNestedLogic(arr, right, logicOp);
return new JObject { [logicOp] = arr };
return new BsonDocument { { logicOp, arr } };
}
private void AddNestedLogic(JArray arr, JToken token, string logicOp)
private void AddNestedLogic(BsonArray arr, BsonValue token, string logicOp)
{
if (token is JObject obj && obj.TryGetValue(logicOp, out var nested) && nested is JArray nestedArr)
if (token is BsonDocument obj && obj.Contains(logicOp))
{
arr.Merge(nestedArr);
var nestedArr = obj[logicOp].AsBsonArray;
arr.AddRange(nestedArr);
}
else
{
@ -52,26 +54,29 @@ namespace SqlSugar.MongoDbCore
}
}
private JToken FieldComparisonExpression(BinaryExpression expr)
private BsonDocument FieldComparisonExpression(BinaryExpression expr)
{
var left = new ExpressionVisitor(_context, new ExpressionVisitorContext());
var right = new ExpressionVisitor(_context, new ExpressionVisitorContext());
JToken field = left.Visit(expr.Left);
JToken value = right.Visit(expr.Right);
var leftIsMember = false;
var rightIsMember = false;
if (left?.visitorContext?.ExpType == typeof(MemberExpression))
BsonValue field = left.Visit(expr.Left);
BsonValue value = right.Visit(expr.Right);
bool leftIsMember = false;
bool rightIsMember = false;
if (left?.visitorContext?.ExpType == typeof(MemberExpression))
{
leftIsMember = true;
}
if (right?.visitorContext?.ExpType == typeof(MemberExpression))
{
rightIsMember = true;
}
string op = expr.NodeType switch
{
ExpressionType.Equal => value.Type == JTokenType.Null ? "$eq" : null,
ExpressionType.NotEqual => value.Type == JTokenType.Null ? "$ne" : "$ne",
ExpressionType.Equal => value.IsBsonNull ? "$eq" : null,
ExpressionType.NotEqual => value.IsBsonNull ? "$ne" : "$ne",
ExpressionType.GreaterThan => "$gt",
ExpressionType.GreaterThanOrEqual => "$gte",
ExpressionType.LessThan => "$lt",
@ -79,15 +84,15 @@ namespace SqlSugar.MongoDbCore
_ => throw new NotSupportedException($"Unsupported binary op: {expr.NodeType}")
};
if (op == null&&leftIsMember&&rightIsMember==false)
return new JObject { [field.ToString()] = value };
else if (op == null && rightIsMember && leftIsMember == false)
return new JObject { [value.ToString()] = field };
if (op == null && leftIsMember && !rightIsMember)
return new BsonDocument { { field.ToString(), value } };
else if (op == null && rightIsMember && !leftIsMember)
return new BsonDocument { { value.ToString(), field } };
return new JObject
{
[field.ToString()] = new JObject { [op] = value }
};
return new BsonDocument
{
{ field.ToString(), new BsonDocument { { op, value } } }
};
}
}

View File

@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq;
using MongoDB.Bson;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
@ -6,36 +7,40 @@ using System.Text;
namespace SqlSugar.MongoDbCore
{
public class FieldPathExtractor
public class FieldPathExtractor
{
MongoNestedTranslatorContext _context;
ExpressionVisitorContext _visitorContext;
public FieldPathExtractor(MongoNestedTranslatorContext context, ExpressionVisitorContext visitorContext)
{
_context = context;
_visitorContext = visitorContext;
}
public string Extract(Expression expr)
{
public BsonValue Extract(Expression expr)
{
var oldExp = expr;
var oldMember = expr as MemberExpression;
var parts = new Stack<string>();
var parts = new Stack<string>();
while (expr is MemberExpression member)
{
parts.Push(member.Member.Name);
expr = member.Expression!;
}
if (expr is ConstantExpression constantExpression)
if (expr is ConstantExpression constantExpression)
{
var value = ExpressionTool.GetMemberValue(oldMember.Member, oldExp);
return MongoDbExpTools.CustomToString(value);
return BsonValue.Create(value);
}
if (_visitorContext != null)
if (_visitorContext != null)
{
_visitorContext.ExpType = typeof(MemberExpression);
}
return string.Join(".", parts);
return BsonValue.Create(string.Join(".", parts));
}
}

View File

@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq;
using MongoDB.Bson;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
@ -6,23 +7,18 @@ using System.Text;
namespace SqlSugar.MongoDbCore
{
public class ValueExtractor
public class ValueExtractor
{
MongoNestedTranslatorContext _context;
public ValueExtractor(MongoNestedTranslatorContext context, ExpressionVisitorContext visitorContext)
{
_context = context;
}
public JToken Extract(ConstantExpression expr)
{
return JToken.FromObject(expr.Value);
}
public static JToken GetValue(Expression expr)
public BsonValue Extract(ConstantExpression expr)
{
var lambda = Expression.Lambda(expr);
var compiled = lambda.Compile();
return JToken.FromObject(compiled.DynamicInvoke());
}
return BsonValue.Create(expr.Value);
}
}
}