mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-10-31 07:49:26 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			169 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using FreeSql.Internal.Model;
 | |
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Data;
 | |
| using System.Data.Common;
 | |
| using System.Linq;
 | |
| using System.Linq.Expressions;
 | |
| using System.Text;
 | |
| 
 | |
| namespace FreeSql.Internal.CommonProvider {
 | |
| 
 | |
| 	abstract partial class UpdateProvider<T1> : IUpdate<T1> where T1 : class {
 | |
| 		protected IFreeSql _orm;
 | |
| 		protected CommonUtils _commonUtils;
 | |
| 		protected CommonExpression _commonExpression;
 | |
| 		protected List<T1> _source = new List<T1>();
 | |
| 		protected Dictionary<string, bool> _ignore = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
 | |
| 		protected TableInfo _table;
 | |
| 		protected StringBuilder _where = new StringBuilder();
 | |
| 		protected StringBuilder _set = new StringBuilder();
 | |
| 		protected List<DbParameter> _params = new List<DbParameter>();
 | |
| 		protected List<DbParameter> _paramsSource = new List<DbParameter>();
 | |
| 
 | |
| 		public UpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) {
 | |
| 			_orm = orm;
 | |
| 			_commonUtils = commonUtils;
 | |
| 			_commonExpression = commonExpression;
 | |
| 			_table = _commonUtils.GetTableByEntity(typeof(T1));
 | |
| 			this.Where(_commonUtils.WhereObject(_table, "", dywhere));
 | |
| 			if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure<T1>();
 | |
| 		}
 | |
| 
 | |
| 		public long ExecuteAffrows() {
 | |
| 			var sql = this.ToSql();
 | |
| 			if (string.IsNullOrEmpty(sql)) return 0;
 | |
| 			return _orm.Ado.ExecuteNonQuery(CommandType.Text, sql, _params.Concat(_paramsSource).ToArray());
 | |
| 		}
 | |
| 		public abstract List<T1> ExecuteUpdated();
 | |
| 
 | |
| 		public IUpdate<T1> IgnoreColumns(Expression<Func<T1, object>> columns) {
 | |
| 			var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, columns?.Body, false).Distinct();
 | |
| 			_ignore.Clear();
 | |
| 			foreach (var col in cols) _ignore.Add(col, true);
 | |
| 			return this;
 | |
| 		}
 | |
| 
 | |
| 		public IUpdate<T1> SetSource(T1 source) => this.SetSource(new[] { source });
 | |
| 		public IUpdate<T1> SetSource(IEnumerable<T1> source) {
 | |
| 			if (source == null || source.Any() == false) return this;
 | |
| 			_source.AddRange(source.Where(a => a != null));
 | |
| 			return this.Where(_source);
 | |
| 		}
 | |
| 
 | |
| 		public IUpdate<T1> Set<TMember>(Expression<Func<T1, TMember>> column, TMember value) {
 | |
| 			var col = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, column?.Body, true);
 | |
| 			if (string.IsNullOrEmpty(col)) return this;
 | |
| 			_set.Append(", ").Append(col).Append(" = ").Append(_commonUtils.QuoteParamterName("p_")).Append(_params.Count);
 | |
| 			_commonUtils.AppendParamter(_params, null, value);
 | |
| 			//foreach (var t in _source) Utils.FillPropertyValue(t, tryf.CsName, value);
 | |
| 			return this;
 | |
| 		}
 | |
| 		public IUpdate<T1> Set<TMember>(Expression<Func<T1, TMember>> binaryExpression) {
 | |
| 			if (binaryExpression?.Body is BinaryExpression == false) return this;
 | |
| 			var cols = new List<SelectColumnInfo>();
 | |
| 			var expt = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, cols, binaryExpression);
 | |
| 			if (cols.Any() == false) return this;
 | |
| 			foreach (var col in cols) {
 | |
| 				if (col.Column.Attribute.IsNullable) {
 | |
| 					var replval = col.Column.Attribute.DbDefautValue;
 | |
| 					if (replval == null) continue;
 | |
| 					var replname = _commonUtils.QuoteSqlName(col.Column.Attribute.Name);
 | |
| 					expt = expt.Replace(replname, _commonUtils.IsNull(replname, _commonUtils.FormatSql("{0}", replval)));
 | |
| 				}
 | |
| 			}
 | |
| 			_set.Append(", ").Append(_commonUtils.QuoteSqlName(cols.First().Column.Attribute.Name)).Append(" = ").Append(expt);
 | |
| 			return this;
 | |
| 		}
 | |
| 		public IUpdate<T1> SetRaw(string sql, object parms = null) {
 | |
| 			if (string.IsNullOrEmpty(sql)) return this;
 | |
| 			_set.Append(", ").Append(sql);
 | |
| 			if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms));
 | |
| 			return this;
 | |
| 		}
 | |
| 
 | |
| 		public IUpdate<T1> Where(Expression<Func<T1, bool>> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, null, expression?.Body));
 | |
| 		public IUpdate<T1> Where(string sql, object parms = null) {
 | |
| 			if (string.IsNullOrEmpty(sql)) return this;
 | |
| 			_where.Append(" AND (").Append(sql).Append(")");
 | |
| 			if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms));
 | |
| 			return this;
 | |
| 		}
 | |
| 		public IUpdate<T1> Where(T1 item) => this.Where(new[] { item });
 | |
| 		public IUpdate<T1> Where(IEnumerable<T1> items) => this.Where(_commonUtils.WhereItems(_table, "", items));
 | |
| 		public IUpdate<T1> WhereExists<TEntity2>(ISelect<TEntity2> select, bool notExists = false) where TEntity2 : class => this.Where($"{(notExists ? "NOT " : "")}EXISTS({select.ToSql("1")})");
 | |
| 
 | |
| 		protected abstract void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys);
 | |
| 		protected abstract void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d);
 | |
| 
 | |
| 		public string ToSql() {
 | |
| 			if (_where.Length == 0) return null;
 | |
| 
 | |
| 			var sb = new StringBuilder();
 | |
| 			sb.Append("UPDATE ").Append(_commonUtils.QuoteSqlName(_table.DbName)).Append(" SET ");
 | |
| 
 | |
| 			if (_set.Length > 0) { //指定 set 更新
 | |
| 				sb.Append(_set.ToString().Substring(2));
 | |
| 
 | |
| 			} else if (_source.Count == 1) { //保存 Source
 | |
| 				_paramsSource.Clear();
 | |
| 				var colidx = 0;
 | |
| 				foreach (var col in _table.Columns.Values) {
 | |
| 					if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.CsName) == false) {
 | |
| 						if (colidx > 0) sb.Append(", ");
 | |
| 						sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(_commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"));
 | |
| 						_commonUtils.AppendParamter(_paramsSource, null, _table.Properties.TryGetValue(col.CsName, out var tryp) ? tryp.GetValue(_source.First()) : DBNull.Value);
 | |
| 						++colidx;
 | |
| 					}
 | |
| 				}
 | |
| 				if (colidx == 0) return null;
 | |
| 
 | |
| 			} else if (_source.Count > 1) { //批量保存 Source
 | |
| 				if (_table.Primarys.Any() == false) return null;
 | |
| 
 | |
| 				var caseWhen = new StringBuilder();
 | |
| 				caseWhen.Append("CASE ");
 | |
| 				ToSqlCase(caseWhen, _table.Primarys);
 | |
| 				//if (_table.Primarys.Length > 1) caseWhen.Append("CONCAT(");
 | |
| 				//var pkidx = 0;
 | |
| 				//foreach (var pk in _table.Primarys) {
 | |
| 				//	if (pkidx > 0) caseWhen.Append(", ");
 | |
| 				//	caseWhen.Append(_commonUtils.QuoteSqlName(pk.Attribute.Name));
 | |
| 				//	++pkidx;
 | |
| 				//}
 | |
| 				//if (_table.Primarys.Length > 1) caseWhen.Append(")");
 | |
| 				var cw = caseWhen.ToString();
 | |
| 
 | |
| 				_paramsSource.Clear();
 | |
| 				var colidx = 0;
 | |
| 				foreach (var col in _table.Columns.Values) {
 | |
| 					if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.CsName) == false) {
 | |
| 						if (colidx > 0) sb.Append(", ");
 | |
| 						sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(cw);
 | |
| 						foreach (var d in _source) {
 | |
| 							sb.Append(" \r\nWHEN ");
 | |
| 							ToSqlWhen(sb, _table.Primarys, d);
 | |
| 							//if (_table.Primarys.Length > 1) sb.Append("CONCAT(");
 | |
| 							//pkidx = 0;
 | |
| 							//foreach (var pk in _table.Primarys) {
 | |
| 							//	if (pkidx > 0) sb.Append(", ");
 | |
| 							//	sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(pk.CsName, out var tryp2) ? tryp2.GetValue(d) : null));
 | |
| 							//	++pkidx;
 | |
| 							//}
 | |
| 							//if (_table.Primarys.Length > 1) sb.Append(")");
 | |
| 							sb.Append(" THEN ").Append(_commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"));
 | |
| 							_commonUtils.AppendParamter(_paramsSource, null, _table.Properties.TryGetValue(col.CsName, out var tryp) ? tryp.GetValue(d) : DBNull.Value);
 | |
| 						}
 | |
| 						sb.Append(" END");
 | |
| 						++colidx;
 | |
| 					}
 | |
| 				}
 | |
| 				if (colidx == 0) return null;
 | |
| 			} else
 | |
| 				return null;
 | |
| 
 | |
| 			sb.Append(" \r\nWHERE ").Append(_where.ToString().Substring(5));
 | |
| 			return sb.ToString();
 | |
| 		}
 | |
| 	}
 | |
| } | 
