Update mongodb

This commit is contained in:
sunkaixuan 2025-05-04 14:02:50 +08:00
parent 1c55ba1929
commit f32f86ad35
9 changed files with 284 additions and 0 deletions

View File

@ -0,0 +1,31 @@
using Npgsql;
using SqlSugar.MongoDbCore;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace MongoDbTest
{
public class ExpTest
{
public static void Init()
{
Expression<Func<Order, bool>> exp = it=>it.Id==1||it.Name=="a";
var json=MongoNestedTranslator.Translate(exp);
var Order = new Order() { Id = 1 };
Expression<Func<Order, bool>> exp2 = it => it.Id == Order.Id || it.Name == "a";
var json2 = MongoNestedTranslator.Translate(exp2);
}
}
public class Order
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsValidate { get; set; }
}
}

View File

@ -9,6 +9,7 @@
<ItemGroup>
<ProjectReference Include="..\MongoDb.Ado.data\MongoDb.Ado.data.csproj" />
<ProjectReference Include="..\SqlSugar.MongoDbCore\SqlSugar.MongoDbCore.csproj" />
</ItemGroup>
</Project>

View File

@ -1,4 +1,5 @@
using MongoDbTest;
//开发中
AdoTest.Init();
ExpTest.Init();
Console.WriteLine("执行完成");

View File

@ -0,0 +1,33 @@
using Newtonsoft.Json.Linq;
using SqlSugar.MongoDbCore.ExpToSql.VisitorItems;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
namespace SqlSugar.MongoDbCore
{
public static class ExpressionVisitor
{
public static JToken Visit(Expression expr)
{
expr = MongoDbExpTools.RemoveConvert(expr);
switch (expr)
{
case BinaryExpression binary:
return BinaryExpressionTranslator.Translate(binary);
case MemberExpression member:
return FieldPathExtractor.GetFieldPath(member);
case ConstantExpression constant:
return ValueExtractor.GetValue(constant);
case UnaryExpression unary:
return Visit(unary);
case LambdaExpression lambda:
return Visit((lambda as LambdaExpression).Body);
default:
throw new NotSupportedException($"Unsupported expression: {expr.NodeType}");
}
}
}
}

View File

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq.Expressions;
using System.Text;
namespace SqlSugar.MongoDbCore
{
public class MongoDbExpTools
{
public static string CustomToString(object value)
{
if (value == null||value==DBNull.Value)
return null;
// 处理数字类型(忽略系统语言)
if (value is IConvertible)
{
if (value is double || value is float || value is decimal || value is int || value is long|| value is uint || value is ulong)
{
return Convert.ToDecimal(value).ToString(CultureInfo.InvariantCulture);
}
else if (value is bool boolValue)
{
return boolValue?"1":"0";
}
}
// 处理时间类型
if (value is TimeSpan ts)
{
return ts.TotalMilliseconds.ToString(CultureInfo.InvariantCulture);
}
// 处理时间类型
if (value is DateTime)
{
return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss.fff");
}
// 处理 DateTimeOffset 类型(返回 UTC 时间,存储时区偏移量)
if (value is DateTimeOffset)
{
var dateTimeOffset = (DateTimeOffset)value;
// 存储 UTC 时间
string utcTime = dateTimeOffset.UtcDateTime.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
// 如果需要存储时区偏移量,可以将偏移量作为额外字段
string timezoneOffset = dateTimeOffset.Offset.ToString();
// 返回两个字段UTC 时间和时区偏移量(可以根据实际需求组合)
return $"{utcTime} UTC{timezoneOffset}";
}
// 默认的ToString
return value.ToString();
}
internal static Expression RemoveConvert(Expression item)
{
for (int i = 0; i < 10; i++)
{
if ((item is UnaryExpression) && (item as UnaryExpression).NodeType == ExpressionType.Convert)
{
item = (item as UnaryExpression).Operand;
}
else
{
break;
}
}
return item;
}
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq.Expressions;
using Newtonsoft.Json.Linq;
namespace SqlSugar.MongoDbCore
{
public static class MongoNestedTranslator
{
public static JObject Translate(Expression expr)
{
return (JObject)ExpressionVisitor.Visit(expr);
}
}
}

View File

@ -0,0 +1,73 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
namespace SqlSugar.MongoDbCore.ExpToSql.VisitorItems
{
public static class BinaryExpressionTranslator
{
public static JToken Translate(BinaryExpression expr)
{
if (expr.NodeType == ExpressionType.AndAlso || expr.NodeType == ExpressionType.OrElse)
{
return LogicalBinaryExpression(expr);
}
return FieldComparisonExpression(expr);
}
private static JToken LogicalBinaryExpression(BinaryExpression expr)
{
string logicOp = expr.NodeType == ExpressionType.AndAlso ? "$and" : "$or";
var left = ExpressionVisitor.Visit(expr.Left);
var right = ExpressionVisitor.Visit(expr.Right);
var arr = new JArray();
AddNestedLogic(arr, left, logicOp);
AddNestedLogic(arr, right, logicOp);
return new JObject { [logicOp] = arr };
}
private static void AddNestedLogic(JArray arr, JToken token, string logicOp)
{
if (token is JObject obj && obj.TryGetValue(logicOp, out var nested) && nested is JArray nestedArr)
{
arr.Merge(nestedArr);
}
else
{
arr.Add(token);
}
}
private static JToken FieldComparisonExpression(BinaryExpression expr)
{
string field = FieldPathExtractor.GetFieldPath(expr.Left);
JToken value = ExpressionVisitor.Visit(expr.Right);
string op = expr.NodeType switch
{
ExpressionType.Equal => value.Type == JTokenType.Null ? "$eq" : null,
ExpressionType.NotEqual => value.Type == JTokenType.Null ? "$ne" : "$ne",
ExpressionType.GreaterThan => "$gt",
ExpressionType.GreaterThanOrEqual => "$gte",
ExpressionType.LessThan => "$lt",
ExpressionType.LessThanOrEqual => "$lte",
_ => throw new NotSupportedException($"Unsupported binary op: {expr.NodeType}")
};
if (op == null)
return new JObject { [field] = value };
return new JObject
{
[field] = new JObject { [op] = value }
};
}
}
}

View File

@ -0,0 +1,30 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
namespace SqlSugar.MongoDbCore.ExpToSql.VisitorItems
{
public static class FieldPathExtractor
{
public static string GetFieldPath(Expression expr)
{
var oldExp = expr;
var oldMember = expr as MemberExpression;
var parts = new Stack<string>();
while (expr is MemberExpression member)
{
parts.Push(member.Member.Name);
expr = member.Expression!;
}
if (expr is ConstantExpression constantExpression)
{
var value = ExpressionTool.GetMemberValue(oldMember.Member, oldExp);
return MongoDbExpTools.CustomToString(value);
}
return string.Join(".", parts);
}
}
}

View File

@ -0,0 +1,23 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
namespace SqlSugar.MongoDbCore.ExpToSql.VisitorItems
{
public static class ValueExtractor
{
public static JToken GetValue(ConstantExpression expr)
{
return JToken.FromObject(expr.Value);
}
public static JToken GetValue(Expression expr)
{
var lambda = Expression.Lambda(expr);
var compiled = lambda.Compile();
return JToken.FromObject(compiled.DynamicInvoke());
}
}
}