mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	- 增加 表达式 .HasValue 和 !.HasValue 的解析支持;
This commit is contained in:
		@@ -269,6 +269,28 @@ namespace FreeSql.Tests {
 | 
				
			|||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
		public void Test1() {
 | 
							public void Test1() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var dcksdkdsk = g.sqlite.Select<NewsArticle>().Where(a => a.testaddtime2.HasValue).ToSql();
 | 
				
			||||||
 | 
								var dcksdkdsk2 = g.sqlite.Select<NewsArticle>().Where(a => !a.testaddtime2.HasValue).ToSql();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var testgrpsql = g.sqlite.Select<TaskBuild>()
 | 
				
			||||||
 | 
									.From<Templates>((a, b) => a.InnerJoin(aa => aa.TemplatesId
 | 
				
			||||||
 | 
									  == b.Id2))
 | 
				
			||||||
 | 
									 .GroupBy((a, b) => b.Title)
 | 
				
			||||||
 | 
									 .ToSql(a => new {
 | 
				
			||||||
 | 
										 a.Key,
 | 
				
			||||||
 | 
										 sss = a.Sum(a.Value.Item1.Id)
 | 
				
			||||||
 | 
									 });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var testgrpsql2 = g.sqlite.Select<TaskBuild>()
 | 
				
			||||||
 | 
									.From<Templates>((a, b) => a.InnerJoin(aa => aa.TemplatesId
 | 
				
			||||||
 | 
									  == b.Id2))
 | 
				
			||||||
 | 
									 .GroupBy((a, b) => b.Title)
 | 
				
			||||||
 | 
									 .ToList(a => new {
 | 
				
			||||||
 | 
										 a.Key,
 | 
				
			||||||
 | 
										 sss = a.Sum(a.Value.Item1.Id)
 | 
				
			||||||
 | 
									 });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var tbid = g.sqlite.Select<TaskBuild>().First().Id;
 | 
								var tbid = g.sqlite.Select<TaskBuild>().First().Id;
 | 
				
			||||||
			var tbidsql = g.sqlite.Update<TaskBuild>().Where(a => a.Id == tbid)
 | 
								var tbidsql = g.sqlite.Update<TaskBuild>().Where(a => a.Id == tbid)
 | 
				
			||||||
				.Set(a => new TaskBuild {
 | 
									.Set(a => new TaskBuild {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -278,7 +278,7 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
		};
 | 
							};
 | 
				
			||||||
		public string ExpressionWhereLambdaNoneForeignObject(List<SelectTableInfo> _tables, TableInfo table, List<SelectColumnInfo> _selectColumnMap, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
 | 
							public string ExpressionWhereLambdaNoneForeignObject(List<SelectTableInfo> _tables, TableInfo table, List<SelectColumnInfo> _selectColumnMap, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
 | 
				
			||||||
			var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table });
 | 
								var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table });
 | 
				
			||||||
			if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool))
 | 
								if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool) && sql.Contains(" IS ") == false && sql.Contains(" = ") == false)
 | 
				
			||||||
				return $"{sql} = {formatSql(true, null)}";
 | 
									return $"{sql} = {formatSql(true, null)}";
 | 
				
			||||||
			switch (sql) {
 | 
								switch (sql) {
 | 
				
			||||||
				case "1":
 | 
									case "1":
 | 
				
			||||||
@@ -291,7 +291,7 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		public string ExpressionWhereLambda(List<SelectTableInfo> _tables, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
 | 
							public string ExpressionWhereLambda(List<SelectTableInfo> _tables, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
 | 
				
			||||||
			var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where });
 | 
								var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where });
 | 
				
			||||||
			if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool))
 | 
								if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool) && sql.Contains(" IS ") == false && sql.Contains(" = ") == false)
 | 
				
			||||||
				return $"{sql} = {formatSql(true, null)}";
 | 
									return $"{sql} = {formatSql(true, null)}";
 | 
				
			||||||
			switch (sql) {
 | 
								switch (sql) {
 | 
				
			||||||
				case "1":
 | 
									case "1":
 | 
				
			||||||
@@ -303,26 +303,26 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		public void ExpressionJoinLambda(List<SelectTableInfo> _tables, SelectTableInfoType tbtype, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
 | 
							public void ExpressionJoinLambda(List<SelectTableInfo> _tables, SelectTableInfoType tbtype, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
 | 
				
			||||||
			var tbidx = _tables.Count;
 | 
								var tbidx = _tables.Count;
 | 
				
			||||||
			var filter = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where });
 | 
								var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where });
 | 
				
			||||||
			if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool))
 | 
								if (exp.NodeType == ExpressionType.MemberAccess && exp.Type == typeof(bool) && sql.Contains(" IS ") == false && sql.Contains(" = ") == false)
 | 
				
			||||||
				filter = $"{filter} = {formatSql(true, null)}";
 | 
									sql = $"{sql} = {formatSql(true, null)}";
 | 
				
			||||||
			switch (filter) {
 | 
								switch (sql) {
 | 
				
			||||||
				case "1":
 | 
									case "1":
 | 
				
			||||||
				case "'t'": filter = "1=1"; break;
 | 
									case "'t'": sql = "1=1"; break;
 | 
				
			||||||
				case "0":
 | 
									case "0":
 | 
				
			||||||
				case "'f'": filter = "1=2"; break;
 | 
									case "'f'": sql = "1=2"; break;
 | 
				
			||||||
				default: break;
 | 
									default: break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (_tables.Count > tbidx) {
 | 
								if (_tables.Count > tbidx) {
 | 
				
			||||||
				_tables[tbidx].Type = tbtype;
 | 
									_tables[tbidx].Type = tbtype;
 | 
				
			||||||
				_tables[tbidx].On = filter;
 | 
									_tables[tbidx].On = sql;
 | 
				
			||||||
				for (var a = tbidx + 1; a < _tables.Count; a++)
 | 
									for (var a = tbidx + 1; a < _tables.Count; a++)
 | 
				
			||||||
					_tables[a].Type = SelectTableInfoType.From;
 | 
										_tables[a].Type = SelectTableInfoType.From;
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				var find = _tables.Where((a, c) => c > 0 && (a.Type == tbtype || a.Type == SelectTableInfoType.From) && string.IsNullOrEmpty(a.On)).LastOrDefault();
 | 
									var find = _tables.Where((a, c) => c > 0 && (a.Type == tbtype || a.Type == SelectTableInfoType.From) && string.IsNullOrEmpty(a.On)).LastOrDefault();
 | 
				
			||||||
				if (find != null) {
 | 
									if (find != null) {
 | 
				
			||||||
					find.Type = tbtype;
 | 
										find.Type = tbtype;
 | 
				
			||||||
					find.On = filter;
 | 
										find.On = sql;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -409,7 +409,14 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
			switch (exp.NodeType) {
 | 
								switch (exp.NodeType) {
 | 
				
			||||||
				case ExpressionType.Not:
 | 
									case ExpressionType.Not:
 | 
				
			||||||
					var notExp = (exp as UnaryExpression)?.Operand;
 | 
										var notExp = (exp as UnaryExpression)?.Operand;
 | 
				
			||||||
					if (notExp.NodeType == ExpressionType.MemberAccess) return $"{ExpressionLambdaToSql(notExp, tsc)} = {formatSql(false, null)}";
 | 
										if (notExp.NodeType == ExpressionType.MemberAccess) {
 | 
				
			||||||
 | 
											var notBody = ExpressionLambdaToSql(notExp, tsc);
 | 
				
			||||||
 | 
											if (notBody.Contains(" IS NULL")) return notBody.Replace(" IS NULL", " IS NOT NULL");
 | 
				
			||||||
 | 
											if (notBody.Contains(" IS NOT NULL")) return notBody.Replace(" IS NOT NULL", " IS NULL");
 | 
				
			||||||
 | 
											if (notBody.Contains("=")) return notBody.Replace("=", "!=");
 | 
				
			||||||
 | 
											if (notBody.Contains("!=")) return notBody.Replace("!=", "=");
 | 
				
			||||||
 | 
											return $"{notBody} = {formatSql(false, null)}";
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
					return $"not({ExpressionLambdaToSql(notExp, tsc)})";
 | 
										return $"not({ExpressionLambdaToSql(notExp, tsc)})";
 | 
				
			||||||
				case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc);
 | 
									case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc);
 | 
				
			||||||
				case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, tsc);
 | 
									case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, tsc);
 | 
				
			||||||
@@ -665,7 +672,8 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
				case ExpressionType.MemberAccess:
 | 
									case ExpressionType.MemberAccess:
 | 
				
			||||||
					var exp4 = exp as MemberExpression;
 | 
										var exp4 = exp as MemberExpression;
 | 
				
			||||||
					if (exp4 != null) {
 | 
										if (exp4 != null) {
 | 
				
			||||||
						if (exp4.Expression != null && exp4.Expression.Type.IsArray == false && exp4.Expression.Type.IsNullableType()) return ExpressionLambdaToSql(exp4.Expression, tsc);
 | 
											if (exp4.Expression != null && exp4.Expression.Type.IsArray == false && exp4.Expression.Type.IsNullableType())
 | 
				
			||||||
 | 
												return exp4.Member.Name == "HasValue" ? $"{ExpressionLambdaToSql(exp4.Expression, tsc)} IS NOT NULL" : ExpressionLambdaToSql(exp4.Expression, tsc);
 | 
				
			||||||
						var extRet = "";
 | 
											var extRet = "";
 | 
				
			||||||
						var memberType = exp4.Expression?.Type ?? exp4.Type;
 | 
											var memberType = exp4.Expression?.Type ?? exp4.Type;
 | 
				
			||||||
						switch (memberType.FullName) {
 | 
											switch (memberType.FullName) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user