diff --git a/Src/Asp.NetCore2/MongoDbTest/UnitTest/QueryWhere.cs b/Src/Asp.NetCore2/MongoDbTest/UnitTest/QueryWhere.cs index bd7f3e0fc..66cbdc586 100644 --- a/Src/Asp.NetCore2/MongoDbTest/UnitTest/QueryWhere.cs +++ b/Src/Asp.NetCore2/MongoDbTest/UnitTest/QueryWhere.cs @@ -53,6 +53,7 @@ namespace MongoDbTest var list5 = db.Queryable().Where(it =>it.CreateDateTime==DateTime.Now.Date).ToList(); var list6 = db.Queryable().Where(it => it.CreateDateTime == DateTime.Now.AddDays(1)).ToList(); + var list7 = db.Queryable().Where(it => it.CreateDateTime.Date == DateTime.Now.AddDays(1)).ToList(); } private static void ValidateStudentData(SqlSugar.SqlSugarClient db) diff --git a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/Models/SqlFuncBinaryExpressionInfo.cs b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/Models/SqlFuncBinaryExpressionInfo.cs new file mode 100644 index 000000000..778583999 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/Models/SqlFuncBinaryExpressionInfo.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar.MongoDb +{ + public class SqlFuncBinaryExpressionInfo + { + public bool IsSqlFunc { get { return LeftIsFunc || RightIsFunc; } } + public bool LeftIsFunc { get; set; } + public bool RightIsFunc { get; set; } + public string LeftMethodName { get; set; } + public string RightMethodName { get; set; } + public SqlFuncBinaryExpressionInfoType methodType { get; set; } = SqlFuncBinaryExpressionInfoType.Default; + public Expression LeftExp { get; set; } + public ExpressionType NodeType { get; set; } + public Expression RightExp { get; set; } + } + public enum SqlFuncBinaryExpressionInfoType + { + Default=1 + } +} diff --git a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/FieldExpressionCase.cs b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/FieldExpressionCase.cs index 1330bb767..880911f02 100644 --- a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/FieldExpressionCase.cs +++ b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/FieldExpressionCase.cs @@ -12,9 +12,12 @@ namespace SqlSugar.MongoDb private BsonDocument FieldComparisonOrCalculationExpression(BinaryExpression expr) { OutParameters(expr, out var field, out var value, out var leftIsMember, out var rightIsMember, out var op); + var sqlFuncInfo = GetSqlFuncBinaryExpressionInfo(leftIsMember, rightIsMember, expr); + if (sqlFuncInfo.IsSqlFunc) + return GetCalculationOperationBySqlFunc(sqlFuncInfo, field, expr.NodeType, value, leftIsMember, rightIsMember); return op == null ? GetCalculationOperation(field, expr.NodeType, value, leftIsMember, rightIsMember) : GetComparisonOperation(expr, field, value, leftIsMember, rightIsMember, op); - } + } } } diff --git a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/Helper.cs b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/Helper.cs index 5d77444c5..26f040cd1 100644 --- a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/Helper.cs +++ b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/Helper.cs @@ -23,7 +23,18 @@ namespace SqlSugar.MongoDb leftIsMember = leftVisitor.visitorContext?.ExpType == typeof(MemberExpression); rightIsMember = rightVisitor.visitorContext?.ExpType == typeof(MemberExpression); - op = expr.NodeType switch + op = GetComparisonOperator(expr); + } + + public static string GetComparisonOperator(BinaryExpression expr) + { + var type = expr.NodeType; + return GetComparisonType(type); + } + + public static string GetComparisonType(ExpressionType type) + { + return type switch { ExpressionType.Equal => "$eq", ExpressionType.NotEqual => "$ne", @@ -33,7 +44,8 @@ namespace SqlSugar.MongoDb ExpressionType.LessThanOrEqual => "$lte", _ => null }; - } + } + private static string GetCalculationType(ExpressionType nodeType) { return nodeType switch diff --git a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/Root.cs b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/Root.cs index b8a528835..f075192ed 100644 --- a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/Root.cs +++ b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/Root.cs @@ -23,10 +23,9 @@ namespace SqlSugar.MongoDb public BsonDocument Extract(BinaryExpression expr) { if (expr.NodeType == ExpressionType.AndAlso || expr.NodeType == ExpressionType.OrElse) - { return LogicalBinaryExpression(expr); - } - return FieldComparisonOrCalculationExpression(expr); + else + return FieldComparisonOrCalculationExpression(expr); } diff --git a/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/SqlFuncExpression.cs b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/SqlFuncExpression.cs new file mode 100644 index 000000000..ce76c77f8 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar.MongoDbCore/ExpToSql/VisitorItems/BinaryExpressionTranslator/SqlFuncExpression.cs @@ -0,0 +1,70 @@ +using MongoDB.Bson; +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar.MongoDb +{ + public partial class BinaryExpressionTranslator + { + private BsonDocument GetCalculationOperationBySqlFunc(SqlFuncBinaryExpressionInfo expressionInfo, BsonValue field, ExpressionType nodeType, BsonValue value, bool leftIsMember, bool rightIsMember) + { + var mongoDbType = BinaryExpressionTranslator.GetComparisonType(expressionInfo.NodeType); + var left = new ExpressionVisitor(_context).Visit(expressionInfo.LeftExp); + var right = new ExpressionVisitor(_context).Visit(expressionInfo.RightExp); + var filter = new BsonDocument("$expr", new BsonDocument(mongoDbType, new BsonArray + { + left, + right + })); + return filter; + } + private SqlFuncBinaryExpressionInfo GetSqlFuncBinaryExpressionInfo(bool leftIsMember, bool rightIsMember, BinaryExpression expr) + { + SqlFuncBinaryExpressionInfo sqlFuncBinaryExpressionInfo = new SqlFuncBinaryExpressionInfo(); + sqlFuncBinaryExpressionInfo.LeftMethodName= GetSystemDateMemberName(MongoDbExpTools.RemoveConvert(expr.Left)); + if (!string.IsNullOrEmpty(sqlFuncBinaryExpressionInfo.LeftMethodName)) + { + sqlFuncBinaryExpressionInfo.LeftIsFunc = true; + } + sqlFuncBinaryExpressionInfo.RightMethodName = GetSystemDateMemberName(MongoDbExpTools.RemoveConvert(expr.Right)); + if (!string.IsNullOrEmpty(sqlFuncBinaryExpressionInfo.RightMethodName)) + { + sqlFuncBinaryExpressionInfo.RightIsFunc = true; + } + sqlFuncBinaryExpressionInfo.LeftExp = MongoDbExpTools.RemoveConvert(expr.Left); + sqlFuncBinaryExpressionInfo.RightExp = MongoDbExpTools.RemoveConvert(expr.Right); + sqlFuncBinaryExpressionInfo.NodeType= expr.NodeType; + return sqlFuncBinaryExpressionInfo; + } + public static string GetSystemDateMemberName(Expression expr) + { + // 只处理 MemberExpression + // 确保是 MemberExpression(访问属性或字段) + if (expr is MemberExpression memberExpr&&ExpressionTool.GetParameters(expr).Count>0) + { + var memberName = memberExpr.Member.Name; + + // 检查名字是否是我们关心的字段 + if (!AllowedDateParts.Contains(memberName)) + return null; + + // 获取访问者对象的类型(例如 x.CreateTime.Year 中的 x.CreateTime) + var expressionType = memberExpr.Expression.Type; + + // 确保它是 System.DateTime(可拓展为 Nullable) + if (expressionType == typeof(DateTime) || expressionType == typeof(DateTime?)) + { + return memberName; + } + } + + return null; + } + private static readonly List AllowedDateParts = new List() + { + "Date", "Year", "Month", "Day", "Hour", "Minute", "Second", "Millisecond" + }; + } +}