mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-12-22 01:05:47 +08:00
pgsql/mysql/sqlserver适配
This commit is contained in:
172
FreeSql/Internal/CommonProvider/UpdateProvider.cs
Normal file
172
FreeSql/Internal/CommonProvider/UpdateProvider.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
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(" = ?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 repltype = col.Column.CsType;
|
||||
if (repltype.FullName.StartsWith("System.Nullable`1[[System.")) repltype = repltype.GenericTypeArguments[0];
|
||||
var replval = Activator.CreateInstance(repltype);
|
||||
if (replval == null) continue;
|
||||
var replname = _commonUtils.QuoteSqlName(col.Column.Attribute.Name);
|
||||
replval = _commonUtils.FormatSql("{0}", replval);
|
||||
expt = expt.Replace(replname, _commonUtils.IsNull(replname, 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.Append(" ").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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user