源代码改用vs默认格式化

This commit is contained in:
28810
2019-06-27 09:40:35 +08:00
parent 873364c7ee
commit f8c3608fda
309 changed files with 73814 additions and 67594 deletions

View File

@ -5,74 +5,91 @@ using System.Data;
using System.Text;
using System.Threading.Tasks;
namespace FreeSql.MySql.Curd {
namespace FreeSql.MySql.Curd
{
class MySqlDelete<T1> : Internal.CommonProvider.DeleteProvider<T1> where T1 : class {
public MySqlDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere)
: base(orm, commonUtils, commonExpression, dywhere) {
}
class MySqlDelete<T1> : Internal.CommonProvider.DeleteProvider<T1> where T1 : class
{
public MySqlDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere)
: base(orm, commonUtils, commonExpression, dywhere)
{
}
public override List<T1> ExecuteDeleted() {
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return new List<T1>();
public override List<T1> ExecuteDeleted()
{
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return new List<T1>();
var sb = new StringBuilder();
sb.Append(sql).Append(" RETURNING ");
var sb = new StringBuilder();
sb.Append(sql).Append(" RETURNING ");
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
sql = sb.ToString();
var dbParms = _params.ToArray();
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms);
_orm.Aop.CurdBefore?.Invoke(this, before);
var ret = new List<T1>();
Exception exception = null;
try {
ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sql, dbParms);
} catch (Exception ex) {
exception = ex;
throw ex;
} finally {
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
async public override Task<List<T1>> ExecuteDeletedAsync() {
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return new List<T1>();
var colidx = 0;
foreach (var col in _table.Columns.Values)
{
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
sql = sb.ToString();
var dbParms = _params.ToArray();
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms);
_orm.Aop.CurdBefore?.Invoke(this, before);
var ret = new List<T1>();
Exception exception = null;
try
{
ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sql, dbParms);
}
catch (Exception ex)
{
exception = ex;
throw ex;
}
finally
{
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
async public override Task<List<T1>> ExecuteDeletedAsync()
{
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return new List<T1>();
var sb = new StringBuilder();
sb.Append(sql).Append(" RETURNING ");
var sb = new StringBuilder();
sb.Append(sql).Append(" RETURNING ");
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
sql = sb.ToString();
var dbParms = _params.ToArray();
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms);
_orm.Aop.CurdBefore?.Invoke(this, before);
var ret = new List<T1>();
Exception exception = null;
try {
ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sql, dbParms);
} catch (Exception ex) {
exception = ex;
throw ex;
} finally {
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
}
var colidx = 0;
foreach (var col in _table.Columns.Values)
{
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
sql = sb.ToString();
var dbParms = _params.ToArray();
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Delete, sql, dbParms);
_orm.Aop.CurdBefore?.Invoke(this, before);
var ret = new List<T1>();
Exception exception = null;
try
{
ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sql, dbParms);
}
catch (Exception ex)
{
exception = ex;
throw ex;
}
finally
{
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
}
}

View File

@ -5,122 +5,151 @@ using System.Data;
using System.Text;
using System.Threading.Tasks;
namespace FreeSql.MySql.Curd {
namespace FreeSql.MySql.Curd
{
class MySqlInsert<T1> : Internal.CommonProvider.InsertProvider<T1> where T1 : class {
public MySqlInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression)
: base(orm, commonUtils, commonExpression) {
}
class MySqlInsert<T1> : Internal.CommonProvider.InsertProvider<T1> where T1 : class
{
public MySqlInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression)
: base(orm, commonUtils, commonExpression)
{
}
public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000);
public override Task<int> ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000);
public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000);
public override Task<long> ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000);
public override List<T1> ExecuteInserted() => base.SplitExecuteInserted(5000, 3000);
public override Task<List<T1>> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000);
public override int ExecuteAffrows() => base.SplitExecuteAffrows(5000, 3000);
public override Task<int> ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(5000, 3000);
public override long ExecuteIdentity() => base.SplitExecuteIdentity(5000, 3000);
public override Task<long> ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(5000, 3000);
public override List<T1> ExecuteInserted() => base.SplitExecuteInserted(5000, 3000);
public override Task<List<T1>> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(5000, 3000);
protected override long RawExecuteIdentity() {
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return 0;
protected override long RawExecuteIdentity()
{
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return 0;
sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();");
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params);
_orm.Aop.CurdBefore?.Invoke(this, before);
long ret = 0;
Exception exception = null;
try {
ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out var trylng) ? trylng : 0;
} catch (Exception ex) {
exception = ex;
throw ex;
} finally {
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
async protected override Task<long> RawExecuteIdentityAsync() {
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return 0;
sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();");
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params);
_orm.Aop.CurdBefore?.Invoke(this, before);
long ret = 0;
Exception exception = null;
try
{
ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _params)), out var trylng) ? trylng : 0;
}
catch (Exception ex)
{
exception = ex;
throw ex;
}
finally
{
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
async protected override Task<long> RawExecuteIdentityAsync()
{
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return 0;
sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();");
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params);
_orm.Aop.CurdBefore?.Invoke(this, before);
long ret = 0;
Exception exception = null;
try {
ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out var trylng) ? trylng : 0;
} catch (Exception ex) {
exception = ex;
throw ex;
} finally {
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
protected override List<T1> RawExecuteInserted() {
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return new List<T1>();
sql = string.Concat(sql, "; SELECT LAST_INSERT_ID();");
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params);
_orm.Aop.CurdBefore?.Invoke(this, before);
long ret = 0;
Exception exception = null;
try
{
ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _params)), out var trylng) ? trylng : 0;
}
catch (Exception ex)
{
exception = ex;
throw ex;
}
finally
{
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
protected override List<T1> RawExecuteInserted()
{
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return new List<T1>();
var sb = new StringBuilder();
sb.Append(sql).Append(" RETURNING ");
var sb = new StringBuilder();
sb.Append(sql).Append(" RETURNING ");
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
sql = sb.ToString();
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params);
_orm.Aop.CurdBefore?.Invoke(this, before);
var ret = new List<T1>();
Exception exception = null;
try {
ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sql, _params);
} catch (Exception ex) {
exception = ex;
throw ex;
} finally {
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
async protected override Task<List<T1>> RawExecuteInsertedAsync() {
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return new List<T1>();
var colidx = 0;
foreach (var col in _table.Columns.Values)
{
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
sql = sb.ToString();
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params);
_orm.Aop.CurdBefore?.Invoke(this, before);
var ret = new List<T1>();
Exception exception = null;
try
{
ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sql, _params);
}
catch (Exception ex)
{
exception = ex;
throw ex;
}
finally
{
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
async protected override Task<List<T1>> RawExecuteInsertedAsync()
{
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return new List<T1>();
var sb = new StringBuilder();
sb.Append(sql).Append(" RETURNING ");
var sb = new StringBuilder();
sb.Append(sql).Append(" RETURNING ");
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
sql = sb.ToString();
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params);
_orm.Aop.CurdBefore?.Invoke(this, before);
var ret = new List<T1>();
Exception exception = null;
try {
ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sql, _params);
} catch (Exception ex) {
exception = ex;
throw ex;
} finally {
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
}
var colidx = 0;
foreach (var col in _table.Columns.Values)
{
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
sql = sb.ToString();
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Insert, sql, _params);
_orm.Aop.CurdBefore?.Invoke(this, before);
var ret = new List<T1>();
Exception exception = null;
try
{
ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sql, _params);
}
catch (Exception ex)
{
exception = ex;
throw ex;
}
finally
{
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
}
}

View File

@ -6,123 +6,145 @@ using System.Linq;
using System.Linq.Expressions;
using System.Text;
namespace FreeSql.MySql.Curd {
namespace FreeSql.MySql.Curd
{
class MySqlSelect<T1> : FreeSql.Internal.CommonProvider.Select1Provider<T1> where T1 : class {
class MySqlSelect<T1> : FreeSql.Internal.CommonProvider.Select1Provider<T1> where T1 : class
{
internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List<SelectTableInfo> _tables, Func<Type, string, string> tableRuleInvoke, IFreeSql _orm) {
if (_orm.CodeFirst.IsAutoSyncStructure)
_orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray());
internal static string ToSqlStatic(CommonUtils _commonUtils, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List<SelectTableInfo> _tables, Func<Type, string, string> tableRuleInvoke, IFreeSql _orm)
{
if (_orm.CodeFirst.IsAutoSyncStructure)
_orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray());
var sb = new StringBuilder();
var sbnav = new StringBuilder();
sb.Append(_select);
if (_distinct) sb.Append("DISTINCT ");
sb.Append(field).Append(" \r\nFROM ");
var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray();
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
for (var a = 0; a < tbsfrom.Length; a++) {
sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias);
if (tbsjoin.Length > 0) {
//如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1
for (var b = 1; b < tbsfrom.Length; b++) {
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias);
if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1");
else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On);
}
break;
} else {
if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")");
if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")");
}
if (a < tbsfrom.Length - 1) sb.Append(", ");
}
foreach (var tb in tbsjoin) {
if (tb.Type == SelectTableInfoType.Parent) continue;
switch (tb.Type) {
case SelectTableInfoType.LeftJoin:
sb.Append(" \r\nLEFT JOIN ");
break;
case SelectTableInfoType.InnerJoin:
sb.Append(" \r\nINNER JOIN ");
break;
case SelectTableInfoType.RightJoin:
sb.Append(" \r\nRIGHT JOIN ");
break;
}
sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")");
}
if (_join.Length > 0) sb.Append(_join);
var sb = new StringBuilder();
var sbnav = new StringBuilder();
sb.Append(_select);
if (_distinct) sb.Append("DISTINCT ");
sb.Append(field).Append(" \r\nFROM ");
var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray();
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
for (var a = 0; a < tbsfrom.Length; a++)
{
sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[a].Table.Type, tbsfrom[a].Table.DbName))).Append(" ").Append(tbsfrom[a].Alias);
if (tbsjoin.Length > 0)
{
//如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1
for (var b = 1; b < tbsfrom.Length; b++)
{
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tbsfrom[b].Table.Type, tbsfrom[b].Table.DbName))).Append(" ").Append(tbsfrom[b].Alias);
if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On)) sb.Append(" ON 1 = 1");
else sb.Append(" ON ").Append(tbsfrom[b].NavigateCondition ?? tbsfrom[b].On);
}
break;
}
else
{
if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")");
if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")");
}
if (a < tbsfrom.Length - 1) sb.Append(", ");
}
foreach (var tb in tbsjoin)
{
if (tb.Type == SelectTableInfoType.Parent) continue;
switch (tb.Type)
{
case SelectTableInfoType.LeftJoin:
sb.Append(" \r\nLEFT JOIN ");
break;
case SelectTableInfoType.InnerJoin:
sb.Append(" \r\nINNER JOIN ");
break;
case SelectTableInfoType.RightJoin:
sb.Append(" \r\nRIGHT JOIN ");
break;
}
sb.Append(_commonUtils.QuoteSqlName(tableRuleInvoke(tb.Table.Type, tb.Table.DbName))).Append(" ").Append(tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition);
if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")");
}
if (_join.Length > 0) sb.Append(_join);
sbnav.Append(_where);
foreach (var tb in _tables) {
if (tb.Type == SelectTableInfoType.Parent) continue;
if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false)
sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")");
}
if (sbnav.Length > 0) {
sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5));
}
if (string.IsNullOrEmpty(_groupby) == false) {
sb.Append(_groupby);
if (string.IsNullOrEmpty(_having) == false)
sb.Append(" \r\nHAVING ").Append(_having.Substring(5));
}
sb.Append(_orderby);
if (_skip > 0 || _limit > 0)
sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1);
sbnav.Append(_where);
foreach (var tb in _tables)
{
if (tb.Type == SelectTableInfoType.Parent) continue;
if (string.IsNullOrEmpty(tb.Table.SelectFilter) == false)
sbnav.Append(" AND (").Append(tb.Table.SelectFilter.Replace("a.", $"{tb.Alias}.")).Append(")");
}
if (sbnav.Length > 0)
{
sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5));
}
if (string.IsNullOrEmpty(_groupby) == false)
{
sb.Append(_groupby);
if (string.IsNullOrEmpty(_having) == false)
sb.Append(" \r\nHAVING ").Append(_having.Substring(5));
}
sb.Append(_orderby);
if (_skip > 0 || _limit > 0)
sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1);
sbnav.Clear();
return sb.ToString();
}
sbnav.Clear();
return sb.ToString();
}
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override ISelect<T1, T2> From<T2>(Expression<Func<ISelectFromExpression<T1>, T2, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3> From<T2, T3>(Expression<Func<ISelectFromExpression<T1>, T2, T3, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4> From<T2, T3, T4>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4, T5> From<T2, T3, T4, T5>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4, T5, T6> From<T2, T3, T4, T5, T6>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4, T5, T6, T7> From<T2, T3, T4, T5, T6, T7>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8> From<T2, T3, T4, T5, T6, T7, T8>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> From<T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2> : FreeSql.Internal.CommonProvider.Select2Provider<T1, T2> where T1 : class where T2 : class {
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T1 : class where T2 : class where T3 : class {
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4> : FreeSql.Internal.CommonProvider.Select4Provider<T1, T2, T3, T4> where T1 : class where T2 : class where T3 : class where T4 : class {
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4, T5> : FreeSql.Internal.CommonProvider.Select5Provider<T1, T2, T3, T4, T5> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class {
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4, T5, T6> : FreeSql.Internal.CommonProvider.Select6Provider<T1, T2, T3, T4, T5, T6> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class {
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4, T5, T6, T7> : FreeSql.Internal.CommonProvider.Select7Provider<T1, T2, T3, T4, T5, T6, T7> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class {
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8> : FreeSql.Internal.CommonProvider.Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class {
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> : FreeSql.Internal.CommonProvider.Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class {
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : FreeSql.Internal.CommonProvider.Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class {
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override ISelect<T1, T2> From<T2>(Expression<Func<ISelectFromExpression<T1>, T2, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3> From<T2, T3>(Expression<Func<ISelectFromExpression<T1>, T2, T3, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4> From<T2, T3, T4>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4, T5> From<T2, T3, T4, T5>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4, T5, T6> From<T2, T3, T4, T5, T6>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4, T5, T6, T7> From<T2, T3, T4, T5, T6, T7>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8> From<T2, T3, T4, T5, T6, T7, T8>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> From<T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2> : FreeSql.Internal.CommonProvider.Select2Provider<T1, T2> where T1 : class where T2 : class
{
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T1 : class where T2 : class where T3 : class
{
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4> : FreeSql.Internal.CommonProvider.Select4Provider<T1, T2, T3, T4> where T1 : class where T2 : class where T3 : class where T4 : class
{
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4, T5> : FreeSql.Internal.CommonProvider.Select5Provider<T1, T2, T3, T4, T5> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class
{
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4, T5, T6> : FreeSql.Internal.CommonProvider.Select6Provider<T1, T2, T3, T4, T5, T6> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class
{
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4, T5, T6, T7> : FreeSql.Internal.CommonProvider.Select7Provider<T1, T2, T3, T4, T5, T6, T7> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class
{
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8> : FreeSql.Internal.CommonProvider.Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class
{
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> : FreeSql.Internal.CommonProvider.Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class
{
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
class MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : FreeSql.Internal.CommonProvider.Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class
{
public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, TableRuleInvoke, _orm);
}
}

View File

@ -7,113 +7,136 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FreeSql.MySql.Curd {
namespace FreeSql.MySql.Curd
{
class MySqlUpdate<T1> : Internal.CommonProvider.UpdateProvider<T1> where T1 : class {
class MySqlUpdate<T1> : Internal.CommonProvider.UpdateProvider<T1> where T1 : class
{
public MySqlUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere)
: base(orm, commonUtils, commonExpression, dywhere) {
}
public MySqlUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere)
: base(orm, commonUtils, commonExpression, dywhere)
{
}
public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000);
public override Task<int> ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000);
public override List<T1> ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000);
public override Task<List<T1>> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000);
public override int ExecuteAffrows() => base.SplitExecuteAffrows(500, 3000);
public override Task<int> ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(500, 3000);
public override List<T1> ExecuteUpdated() => base.SplitExecuteUpdated(500, 3000);
public override Task<List<T1>> ExecuteUpdatedAsync() => base.SplitExecuteUpdatedAsync(500, 3000);
protected override List<T1> RawExecuteUpdated() {
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return new List<T1>();
protected override List<T1> RawExecuteUpdated()
{
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return new List<T1>();
var sb = new StringBuilder();
sb.Append(sql).Append(" RETURNING ");
var sb = new StringBuilder();
sb.Append(sql).Append(" RETURNING ");
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
sql = sb.ToString();
var dbParms = _params.Concat(_paramsSource).ToArray();
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms);
_orm.Aop.CurdBefore?.Invoke(this, before);
var ret = new List<T1>();
Exception exception = null;
try {
ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sql, dbParms);
ValidateVersionAndThrow(ret.Count);
} catch (Exception ex) {
exception = ex;
throw ex;
} finally {
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
async protected override Task<List<T1>> RawExecuteUpdatedAsync() {
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return new List<T1>();
var colidx = 0;
foreach (var col in _table.Columns.Values)
{
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
sql = sb.ToString();
var dbParms = _params.Concat(_paramsSource).ToArray();
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms);
_orm.Aop.CurdBefore?.Invoke(this, before);
var ret = new List<T1>();
Exception exception = null;
try
{
ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sql, dbParms);
ValidateVersionAndThrow(ret.Count);
}
catch (Exception ex)
{
exception = ex;
throw ex;
}
finally
{
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
async protected override Task<List<T1>> RawExecuteUpdatedAsync()
{
var sql = this.ToSql();
if (string.IsNullOrEmpty(sql)) return new List<T1>();
var sb = new StringBuilder();
sb.Append(sql).Append(" RETURNING ");
var sb = new StringBuilder();
sb.Append(sql).Append(" RETURNING ");
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
sql = sb.ToString();
var dbParms = _params.Concat(_paramsSource).ToArray();
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms);
_orm.Aop.CurdBefore?.Invoke(this, before);
var ret = new List<T1>();
Exception exception = null;
try {
ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sql, dbParms);
ValidateVersionAndThrow(ret.Count);
} catch (Exception ex) {
exception = ex;
throw ex;
} finally {
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
var colidx = 0;
foreach (var col in _table.Columns.Values)
{
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
sql = sb.ToString();
var dbParms = _params.Concat(_paramsSource).ToArray();
var before = new Aop.CurdBeforeEventArgs(_table.Type, Aop.CurdType.Update, sql, dbParms);
_orm.Aop.CurdBefore?.Invoke(this, before);
var ret = new List<T1>();
Exception exception = null;
try
{
ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sql, dbParms);
ValidateVersionAndThrow(ret.Count);
}
catch (Exception ex)
{
exception = ex;
throw ex;
}
finally
{
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfter?.Invoke(this, after);
}
this.ClearData();
return ret;
}
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) {
if (_table.Primarys.Length == 1) {
caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name)));
return;
}
caseWhen.Append("CONCAT(");
var pkidx = 0;
foreach (var pk in _table.Primarys) {
if (pkidx > 0) caseWhen.Append(", ");
caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name)));
++pkidx;
}
caseWhen.Append(")");
}
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys)
{
if (_table.Primarys.Length == 1)
{
caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name)));
return;
}
caseWhen.Append("CONCAT(");
var pkidx = 0;
foreach (var pk in _table.Primarys)
{
if (pkidx > 0) caseWhen.Append(", ");
caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name)));
++pkidx;
}
caseWhen.Append(")");
}
protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) {
if (_table.Primarys.Length == 1) {
sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d)));
return;
}
sb.Append("CONCAT(");
var pkidx = 0;
foreach (var pk in _table.Primarys) {
if (pkidx > 0) sb.Append(", ");
sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d)));
++pkidx;
}
sb.Append(")");
}
}
protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d)
{
if (_table.Primarys.Length == 1)
{
sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d)));
return;
}
sb.Append("CONCAT(");
var pkidx = 0;
foreach (var pk in _table.Primarys)
{
if (pkidx > 0) sb.Append(", ");
sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d)));
++pkidx;
}
sb.Append(")");
}
}
}

View File

@ -7,57 +7,66 @@ using System.Data.Common;
using System.Text;
using System.Threading;
namespace FreeSql.MySql {
class MySqlAdo : FreeSql.Internal.CommonProvider.AdoProvider {
namespace FreeSql.MySql
{
class MySqlAdo : FreeSql.Internal.CommonProvider.AdoProvider
{
public MySqlAdo() : base(DataType.MySql) { }
public MySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.MySql) {
base._util = util;
if (!string.IsNullOrEmpty(masterConnectionString))
MasterPool = new MySqlConnectionPool("主库", masterConnectionString, null, null);
if (slaveConnectionStrings != null) {
foreach (var slaveConnectionString in slaveConnectionStrings) {
var slavePool = new MySqlConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables));
SlavePools.Add(slavePool);
}
}
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
public override object AddslashesProcessParam(object param, Type mapType) {
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType())
param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?)
return (bool)param ? 1 : 0;
else if (param is string || param is char)
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
else if (param is Enum)
return string.Concat("'", param.ToString().Replace("'", "''"), "'"); //((Enum)val).ToInt64();
else if (decimal.TryParse(string.Concat(param), out var trydec))
return param;
else if (param is DateTime || param is DateTime?)
return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'");
else if (param is TimeSpan || param is TimeSpan?)
return ((TimeSpan)param).Ticks / 10;
else if (param is MygisGeometry)
return string.Concat("ST_GeomFromText('", (param as MygisGeometry).AsText().Replace("'", "''"), "')");
else if (param is IEnumerable) {
var sb = new StringBuilder();
var ie = param as IEnumerable;
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
}
public MySqlAdo() : base(DataType.MySql) { }
public MySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings) : base(DataType.MySql)
{
base._util = util;
if (!string.IsNullOrEmpty(masterConnectionString))
MasterPool = new MySqlConnectionPool("主库", masterConnectionString, null, null);
if (slaveConnectionStrings != null)
{
foreach (var slaveConnectionString in slaveConnectionStrings)
{
var slavePool = new MySqlConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables));
SlavePools.Add(slavePool);
}
}
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
public override object AddslashesProcessParam(object param, Type mapType)
{
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType())
param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?)
return (bool)param ? 1 : 0;
else if (param is string || param is char)
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
else if (param is Enum)
return string.Concat("'", param.ToString().Replace("'", "''"), "'"); //((Enum)val).ToInt64();
else if (decimal.TryParse(string.Concat(param), out var trydec))
return param;
else if (param is DateTime || param is DateTime?)
return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'");
else if (param is TimeSpan || param is TimeSpan?)
return ((TimeSpan)param).Ticks / 10;
else if (param is MygisGeometry)
return string.Concat("ST_GeomFromText('", (param as MygisGeometry).AsText().Replace("'", "''"), "')");
else if (param is IEnumerable)
{
var sb = new StringBuilder();
var ie = param as IEnumerable;
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
}
protected override DbCommand CreateCommand() {
return new MySqlCommand();
}
protected override DbCommand CreateCommand()
{
return new MySqlCommand();
}
protected override void ReturnConnection(ObjectPool<DbConnection> pool, Object<DbConnection> conn, Exception ex) {
(pool as MySqlConnectionPool).Return(conn, ex);
}
protected override void ReturnConnection(ObjectPool<DbConnection> pool, Object<DbConnection> conn, Exception ex)
{
(pool as MySqlConnectionPool).Return(conn, ex);
}
protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj);
}
protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj);
}
}

View File

@ -8,170 +8,210 @@ using System.Data.Common;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace FreeSql.MySql {
namespace FreeSql.MySql
{
class MySqlConnectionPool : ObjectPool<DbConnection> {
class MySqlConnectionPool : ObjectPool<DbConnection>
{
internal Action availableHandler;
internal Action unavailableHandler;
internal Action availableHandler;
internal Action unavailableHandler;
public MySqlConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) {
var policy = new MySqlConnectionPoolPolicy {
_pool = this,
Name = name
};
this.Policy = policy;
policy.ConnectionString = connectionString;
public MySqlConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null)
{
var policy = new MySqlConnectionPoolPolicy
{
_pool = this,
Name = name
};
this.Policy = policy;
policy.ConnectionString = connectionString;
this.availableHandler = availableHandler;
this.unavailableHandler = unavailableHandler;
}
this.availableHandler = availableHandler;
this.unavailableHandler = unavailableHandler;
}
public void Return(Object<DbConnection> obj, Exception exception, bool isRecreate = false) {
if (exception != null && exception is MySqlException) {
try { if (obj.Value.Ping() == false) obj.Value.Open(); } catch { base.SetUnavailable(exception); }
}
base.Return(obj, isRecreate);
}
}
public void Return(Object<DbConnection> obj, Exception exception, bool isRecreate = false)
{
if (exception != null && exception is MySqlException)
{
try { if (obj.Value.Ping() == false) obj.Value.Open(); } catch { base.SetUnavailable(exception); }
}
base.Return(obj, isRecreate);
}
}
class MySqlConnectionPoolPolicy : IPolicy<DbConnection> {
class MySqlConnectionPoolPolicy : IPolicy<DbConnection>
{
internal MySqlConnectionPool _pool;
public string Name { get; set; } = "MySql MySqlConnection 对象池";
public int PoolSize { get; set; } = 100;
public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10);
public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero;
public int AsyncGetCapacity { get; set; } = 10000;
public bool IsThrowGetTimeoutException { get; set; } = true;
public int CheckAvailableInterval { get; set; } = 5;
internal MySqlConnectionPool _pool;
public string Name { get; set; } = "MySql MySqlConnection 对象池";
public int PoolSize { get; set; } = 100;
public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10);
public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero;
public int AsyncGetCapacity { get; set; } = 10000;
public bool IsThrowGetTimeoutException { get; set; } = true;
public int CheckAvailableInterval { get; set; } = 5;
static ConcurrentDictionary<string, int> dicConnStrIncr = new ConcurrentDictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
private string _connectionString;
public string ConnectionString {
get => _connectionString;
set {
_connectionString = value ?? "";
static ConcurrentDictionary<string, int> dicConnStrIncr = new ConcurrentDictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
private string _connectionString;
public string ConnectionString
{
get => _connectionString;
set
{
_connectionString = value ?? "";
var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)";
var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1);
PoolSize = poolsize + connStrIncr;
_connectionString = m.Success ?
Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
$"{_connectionString};Max pool size={PoolSize}";
var pattern = @"Max\s*pool\s*size\s*=\s*(\d+)";
var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
var connStrIncr = dicConnStrIncr.AddOrUpdate(_connectionString, 1, (oldkey, oldval) => oldval + 1);
PoolSize = poolsize + connStrIncr;
_connectionString = m.Success ?
Regex.Replace(_connectionString, pattern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
$"{_connectionString};Max pool size={PoolSize}";
pattern = @"Connection\s*LifeTime\s*=\s*(\d+)";
m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
if (m.Success) {
IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value));
_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
}
pattern = @"Connection\s*LifeTime\s*=\s*(\d+)";
m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
if (m.Success)
{
IdleTimeout = TimeSpan.FromSeconds(int.Parse(m.Groups[1].Value));
_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
}
var minPoolSize = 0;
pattern = @"Min\s*pool\s*size\s*=\s*(\d+)";
m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
if (m.Success) {
minPoolSize = int.Parse(m.Groups[1].Value);
_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
}
var minPoolSize = 0;
pattern = @"Min\s*pool\s*size\s*=\s*(\d+)";
m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
if (m.Success)
{
minPoolSize = int.Parse(m.Groups[1].Value);
_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
}
FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize);
}
}
FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize);
}
}
public bool OnCheckAvailable(Object<DbConnection> obj) {
if (obj.Value.State == ConnectionState.Closed) obj.Value.Open();
return obj.Value.Ping(true);
}
public bool OnCheckAvailable(Object<DbConnection> obj)
{
if (obj.Value.State == ConnectionState.Closed) obj.Value.Open();
return obj.Value.Ping(true);
}
public DbConnection OnCreate() {
var conn = new MySqlConnection(_connectionString);
return conn;
}
public DbConnection OnCreate()
{
var conn = new MySqlConnection(_connectionString);
return conn;
}
public void OnDestroy(DbConnection obj) {
if (obj.State != ConnectionState.Closed) obj.Close();
obj.Dispose();
}
public void OnDestroy(DbConnection obj)
{
if (obj.State != ConnectionState.Closed) obj.Close();
obj.Dispose();
}
public void OnGet(Object<DbConnection> obj) {
public void OnGet(Object<DbConnection> obj)
{
if (_pool.IsAvailable) {
if (_pool.IsAvailable)
{
if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false) {
if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false)
{
try {
obj.Value.Open();
} catch (Exception ex) {
if (_pool.SetUnavailable(ex) == true)
throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}");
}
}
}
}
try
{
obj.Value.Open();
}
catch (Exception ex)
{
if (_pool.SetUnavailable(ex) == true)
throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}");
}
}
}
}
async public Task OnGetAsync(Object<DbConnection> obj) {
async public Task OnGetAsync(Object<DbConnection> obj)
{
if (_pool.IsAvailable) {
if (_pool.IsAvailable)
{
if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false) {
if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false)
{
try {
await obj.Value.OpenAsync();
} catch (Exception ex) {
if (_pool.SetUnavailable(ex) == true)
throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}");
}
}
}
}
try
{
await obj.Value.OpenAsync();
}
catch (Exception ex)
{
if (_pool.SetUnavailable(ex) == true)
throw new Exception($"【{this.Name}】状态不可用,等待后台检查程序恢复方可使用。{ex.Message}");
}
}
}
}
public void OnGetTimeout() {
public void OnGetTimeout()
{
}
}
public void OnReturn(Object<DbConnection> obj) {
public void OnReturn(Object<DbConnection> obj)
{
}
}
public void OnAvailable() {
_pool.availableHandler?.Invoke();
}
public void OnAvailable()
{
_pool.availableHandler?.Invoke();
}
public void OnUnavailable() {
_pool.unavailableHandler?.Invoke();
}
}
public void OnUnavailable()
{
_pool.unavailableHandler?.Invoke();
}
}
static class DbConnectionExtensions {
static class DbConnectionExtensions
{
static DbCommand PingCommand(DbConnection conn) {
var cmd = conn.CreateCommand();
cmd.CommandTimeout = 5;
cmd.CommandText = "select 1";
return cmd;
}
public static bool Ping(this DbConnection that, bool isThrow = false) {
try {
PingCommand(that).ExecuteNonQuery();
return true;
} catch {
if (that.State != ConnectionState.Closed) try { that.Close(); } catch { }
if (isThrow) throw;
return false;
}
}
async public static Task<bool> PingAsync(this DbConnection that, bool isThrow = false) {
try {
await PingCommand(that).ExecuteNonQueryAsync();
return true;
} catch {
if (that.State != ConnectionState.Closed) try { that.Close(); } catch { }
if (isThrow) throw;
return false;
}
}
}
static DbCommand PingCommand(DbConnection conn)
{
var cmd = conn.CreateCommand();
cmd.CommandTimeout = 5;
cmd.CommandText = "select 1";
return cmd;
}
public static bool Ping(this DbConnection that, bool isThrow = false)
{
try
{
PingCommand(that).ExecuteNonQuery();
return true;
}
catch
{
if (that.State != ConnectionState.Closed) try { that.Close(); } catch { }
if (isThrow) throw;
return false;
}
}
async public static Task<bool> PingAsync(this DbConnection that, bool isThrow = false)
{
try
{
await PingCommand(that).ExecuteNonQueryAsync();
return true;
}
catch
{
if (that.State != ConnectionState.Closed) try { that.Close(); } catch { }
if (isThrow) throw;
return false;
}
}
}
}

View File

@ -4,289 +4,338 @@ using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
public struct MygisCoordinate2D : IEquatable<MygisCoordinate2D> {
public double X { get; }
public double Y { get; }
public MygisCoordinate2D(double x, double y) { X = x; Y = y; }
public struct MygisCoordinate2D : IEquatable<MygisCoordinate2D>
{
public double X { get; }
public double Y { get; }
public MygisCoordinate2D(double x, double y) { X = x; Y = y; }
public bool Equals(MygisCoordinate2D c) => X == c.X && Y == c.Y;
public override int GetHashCode() => X.GetHashCode() ^ MygisGeometry.RotateShift(Y.GetHashCode(), sizeof(int) / 2);
public override bool Equals(object obj) => obj is MygisCoordinate2D && Equals((MygisCoordinate2D) obj);
public static bool operator ==(MygisCoordinate2D left, MygisCoordinate2D right) => Equals(left, right);
public static bool operator !=(MygisCoordinate2D left, MygisCoordinate2D right) => !Equals(left, right);
public bool Equals(MygisCoordinate2D c) => X == c.X && Y == c.Y;
public override int GetHashCode() => X.GetHashCode() ^ MygisGeometry.RotateShift(Y.GetHashCode(), sizeof(int) / 2);
public override bool Equals(object obj) => obj is MygisCoordinate2D && Equals((MygisCoordinate2D)obj);
public static bool operator ==(MygisCoordinate2D left, MygisCoordinate2D right) => Equals(left, right);
public static bool operator !=(MygisCoordinate2D left, MygisCoordinate2D right) => !Equals(left, right);
}
public abstract class MygisGeometry {
protected abstract int GetLenHelper();
internal int GetLen(bool includeSRID) => 5 + (SRID == 0 || !includeSRID ? 0 : 4) + GetLenHelper();
public uint SRID { get; set; } = 0;
internal static int RotateShift(int val, int shift) => (val << shift) | (val >> (sizeof(int) - shift));
public override string ToString() => this.AsText();
public string AsText() {
if (this is MygisPoint) {
var obj = this as MygisPoint;
return $"POINT({obj.X} {obj.Y})";
}
if (this is MygisLineString) {
var obj = this as MygisLineString;
return obj?.PointCount > 0 ? $"LINESTRING({string.Join(",", obj.Select(a => $"{a.X} {a.Y}"))})" : null;
}
if (this is MygisPolygon) {
var obj = (this as MygisPolygon).Where(z => z.Count() > 1 && z.First().Equals(z.Last()));
return obj.Any() ? $"POLYGON(({string.Join("),(", obj.Select(c => string.Join(",", c.Select(a => $"{a.X} {a.Y}"))))}))" : null;
}
if (this is MygisMultiPoint) {
var obj = this as MygisMultiPoint;
return obj?.PointCount > 0 ? $"MULTIPOINT({string.Join(",", obj.Select(a => $"{a.X} {a.Y}"))})" : null;
}
if (this is MygisMultiLineString) {
var obj = this as MygisMultiLineString;
return obj.LineCount > 0 ? $"MULTILINESTRING(({string.Join("),(", obj.Select(c => string.Join(",", c.Select(a => $"{a.X} {a.Y}"))))}))" : null;
}
if (this is MygisMultiPolygon) {
var obj = (this as MygisMultiPolygon)?.Where(z => z.Where(y => y.Count() > 1 && y.First().Equals(y.Last())).Any());
return obj.Any() ? $"MULTIPOLYGON((({string.Join(")),((", obj.Select(d => string.Join("),(", d.Select(c => string.Join(",", c.Select(a => $"{a.X} {a.Y}"))))))})))" : null;
}
return base.ToString();
}
static readonly Regex regexMygisPoint = new Regex(@"\s*(-?\d+\.?\d*)\s+(-?\d+\.?\d*)\s*");
static readonly Regex regexSplit1 = new Regex(@"\)\s*,\s*\(");
static readonly Regex regexSplit2 = new Regex(@"\)\s*\)\s*,\s*\(\s*\(");
public static MygisGeometry Parse(string wkt) {
if (string.IsNullOrEmpty(wkt)) return null;
wkt = wkt.Trim();
if (wkt.StartsWith("point", StringComparison.CurrentCultureIgnoreCase)) return ParsePoint(wkt.Substring(5).Trim('(', ')'));
else if (wkt.StartsWith("linestring", StringComparison.CurrentCultureIgnoreCase)) return new MygisLineString(ParseLineString(wkt.Substring(10).Trim('(', ')')));
else if (wkt.StartsWith("polygon", StringComparison.CurrentCultureIgnoreCase)) return new MygisPolygon(ParsePolygon(wkt.Substring(7).Trim('(', ')')));
else if (wkt.StartsWith("multipoint", StringComparison.CurrentCultureIgnoreCase)) return new MygisMultiPoint(ParseLineString(wkt.Substring(10).Trim('(', ')')));
else if (wkt.StartsWith("multilinestring", StringComparison.CurrentCultureIgnoreCase)) return new MygisMultiLineString(ParseMultiLineString(wkt.Substring(15).Trim('(', ')')));
else if (wkt.StartsWith("multipolygon", StringComparison.CurrentCultureIgnoreCase)) return new MygisMultiPolygon(ParseMultiPolygon(wkt.Substring(12).Trim('(', ')')));
throw new NotImplementedException($"MygisGeometry.Parse 未实现 \"{wkt}\"");
}
static MygisPoint ParsePoint(string str) {
var m = regexMygisPoint.Match(str);
if (m.Success == false) return null;
return new MygisPoint(double.TryParse(m.Groups[1].Value, out var tryd) ? tryd : 0, double.TryParse(m.Groups[2].Value, out tryd) ? tryd : 0);
}
static MygisCoordinate2D[] ParseLineString(string str) {
var ms = regexMygisPoint.Matches(str);
var points = new MygisCoordinate2D[ms.Count];
for (var a = 0; a < ms.Count; a++) points[a] = new MygisCoordinate2D(double.TryParse(ms[a].Groups[1].Value, out var tryd) ? tryd : 0, double.TryParse(ms[a].Groups[2].Value, out tryd) ? tryd : 0);
return points;
}
static MygisCoordinate2D[][] ParsePolygon(string str) {
return regexSplit1.Split(str).Select(s => ParseLineString(s)).Where(a => a.Length > 1 && a.First().Equals(a.Last())).ToArray();
}
static MygisLineString[] ParseMultiLineString(string str) {
return regexSplit1.Split(str).Select(s => new MygisLineString(ParseLineString(s))).ToArray();
}
static MygisPolygon[] ParseMultiPolygon(string str) {
return regexSplit2.Split(str).Select(s => new MygisPolygon(ParsePolygon(s))).ToArray();
}
public abstract class MygisGeometry
{
protected abstract int GetLenHelper();
internal int GetLen(bool includeSRID) => 5 + (SRID == 0 || !includeSRID ? 0 : 4) + GetLenHelper();
public uint SRID { get; set; } = 0;
internal static int RotateShift(int val, int shift) => (val << shift) | (val >> (sizeof(int) - shift));
public override string ToString() => this.AsText();
public string AsText()
{
if (this is MygisPoint)
{
var obj = this as MygisPoint;
return $"POINT({obj.X} {obj.Y})";
}
if (this is MygisLineString)
{
var obj = this as MygisLineString;
return obj?.PointCount > 0 ? $"LINESTRING({string.Join(",", obj.Select(a => $"{a.X} {a.Y}"))})" : null;
}
if (this is MygisPolygon)
{
var obj = (this as MygisPolygon).Where(z => z.Count() > 1 && z.First().Equals(z.Last()));
return obj.Any() ? $"POLYGON(({string.Join("),(", obj.Select(c => string.Join(",", c.Select(a => $"{a.X} {a.Y}"))))}))" : null;
}
if (this is MygisMultiPoint)
{
var obj = this as MygisMultiPoint;
return obj?.PointCount > 0 ? $"MULTIPOINT({string.Join(",", obj.Select(a => $"{a.X} {a.Y}"))})" : null;
}
if (this is MygisMultiLineString)
{
var obj = this as MygisMultiLineString;
return obj.LineCount > 0 ? $"MULTILINESTRING(({string.Join("),(", obj.Select(c => string.Join(",", c.Select(a => $"{a.X} {a.Y}"))))}))" : null;
}
if (this is MygisMultiPolygon)
{
var obj = (this as MygisMultiPolygon)?.Where(z => z.Where(y => y.Count() > 1 && y.First().Equals(y.Last())).Any());
return obj.Any() ? $"MULTIPOLYGON((({string.Join(")),((", obj.Select(d => string.Join("),(", d.Select(c => string.Join(",", c.Select(a => $"{a.X} {a.Y}"))))))})))" : null;
}
return base.ToString();
}
static readonly Regex regexMygisPoint = new Regex(@"\s*(-?\d+\.?\d*)\s+(-?\d+\.?\d*)\s*");
static readonly Regex regexSplit1 = new Regex(@"\)\s*,\s*\(");
static readonly Regex regexSplit2 = new Regex(@"\)\s*\)\s*,\s*\(\s*\(");
public static MygisGeometry Parse(string wkt)
{
if (string.IsNullOrEmpty(wkt)) return null;
wkt = wkt.Trim();
if (wkt.StartsWith("point", StringComparison.CurrentCultureIgnoreCase)) return ParsePoint(wkt.Substring(5).Trim('(', ')'));
else if (wkt.StartsWith("linestring", StringComparison.CurrentCultureIgnoreCase)) return new MygisLineString(ParseLineString(wkt.Substring(10).Trim('(', ')')));
else if (wkt.StartsWith("polygon", StringComparison.CurrentCultureIgnoreCase)) return new MygisPolygon(ParsePolygon(wkt.Substring(7).Trim('(', ')')));
else if (wkt.StartsWith("multipoint", StringComparison.CurrentCultureIgnoreCase)) return new MygisMultiPoint(ParseLineString(wkt.Substring(10).Trim('(', ')')));
else if (wkt.StartsWith("multilinestring", StringComparison.CurrentCultureIgnoreCase)) return new MygisMultiLineString(ParseMultiLineString(wkt.Substring(15).Trim('(', ')')));
else if (wkt.StartsWith("multipolygon", StringComparison.CurrentCultureIgnoreCase)) return new MygisMultiPolygon(ParseMultiPolygon(wkt.Substring(12).Trim('(', ')')));
throw new NotImplementedException($"MygisGeometry.Parse 未实现 \"{wkt}\"");
}
static MygisPoint ParsePoint(string str)
{
var m = regexMygisPoint.Match(str);
if (m.Success == false) return null;
return new MygisPoint(double.TryParse(m.Groups[1].Value, out var tryd) ? tryd : 0, double.TryParse(m.Groups[2].Value, out tryd) ? tryd : 0);
}
static MygisCoordinate2D[] ParseLineString(string str)
{
var ms = regexMygisPoint.Matches(str);
var points = new MygisCoordinate2D[ms.Count];
for (var a = 0; a < ms.Count; a++) points[a] = new MygisCoordinate2D(double.TryParse(ms[a].Groups[1].Value, out var tryd) ? tryd : 0, double.TryParse(ms[a].Groups[2].Value, out tryd) ? tryd : 0);
return points;
}
static MygisCoordinate2D[][] ParsePolygon(string str)
{
return regexSplit1.Split(str).Select(s => ParseLineString(s)).Where(a => a.Length > 1 && a.First().Equals(a.Last())).ToArray();
}
static MygisLineString[] ParseMultiLineString(string str)
{
return regexSplit1.Split(str).Select(s => new MygisLineString(ParseLineString(s))).ToArray();
}
static MygisPolygon[] ParseMultiPolygon(string str)
{
return regexSplit2.Split(str).Select(s => new MygisPolygon(ParsePolygon(s))).ToArray();
}
}
public class MygisPoint : MygisGeometry, IEquatable<MygisPoint> {
MygisCoordinate2D _coord;
protected override int GetLenHelper() => 16;
public double X => _coord.X;
public double Y => _coord.Y;
public class MygisPoint : MygisGeometry, IEquatable<MygisPoint>
{
MygisCoordinate2D _coord;
protected override int GetLenHelper() => 16;
public double X => _coord.X;
public double Y => _coord.Y;
public MygisPoint(double x, double y) {
_coord = new MygisCoordinate2D(x, y);
}
public MygisPoint(double x, double y)
{
_coord = new MygisCoordinate2D(x, y);
}
public bool Equals(MygisPoint other) => !ReferenceEquals(other, null) && _coord.Equals(other._coord);
public override bool Equals(object obj) => Equals(obj as MygisPoint);
public static bool operator ==(MygisPoint x, MygisPoint y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y);
public static bool operator !=(MygisPoint x, MygisPoint y) => !(x == y);
public override int GetHashCode() => X.GetHashCode() ^ RotateShift(Y.GetHashCode(), sizeof(int) / 2);
public bool Equals(MygisPoint other) => !ReferenceEquals(other, null) && _coord.Equals(other._coord);
public override bool Equals(object obj) => Equals(obj as MygisPoint);
public static bool operator ==(MygisPoint x, MygisPoint y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y);
public static bool operator !=(MygisPoint x, MygisPoint y) => !(x == y);
public override int GetHashCode() => X.GetHashCode() ^ RotateShift(Y.GetHashCode(), sizeof(int) / 2);
}
public class MygisLineString : MygisGeometry, IEquatable<MygisLineString>, IEnumerable<MygisCoordinate2D> {
readonly MygisCoordinate2D[] _points;
protected override int GetLenHelper() => 4 + _points.Length * 16;
public IEnumerator<MygisCoordinate2D> GetEnumerator() => ((IEnumerable<MygisCoordinate2D>) _points).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public MygisCoordinate2D this[int index] => _points[index];
public int PointCount => _points.Length;
public class MygisLineString : MygisGeometry, IEquatable<MygisLineString>, IEnumerable<MygisCoordinate2D>
{
readonly MygisCoordinate2D[] _points;
protected override int GetLenHelper() => 4 + _points.Length * 16;
public IEnumerator<MygisCoordinate2D> GetEnumerator() => ((IEnumerable<MygisCoordinate2D>)_points).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public MygisCoordinate2D this[int index] => _points[index];
public int PointCount => _points.Length;
public MygisLineString(IEnumerable<MygisCoordinate2D> points) {
_points = points.ToArray();
}
public MygisLineString(MygisCoordinate2D[] points) {
_points = points;
}
public MygisLineString(IEnumerable<MygisCoordinate2D> points)
{
_points = points.ToArray();
}
public MygisLineString(MygisCoordinate2D[] points)
{
_points = points;
}
public bool Equals(MygisLineString other) {
if (ReferenceEquals(other, null)) return false;
if (_points.Length != other._points.Length) return false;
for (var i = 0; i < _points.Length; i++)
if (!_points[i].Equals(other._points[i])) return false;
return true;
}
public override bool Equals(object obj) => Equals(obj as MygisLineString);
public static bool operator ==(MygisLineString x, MygisLineString y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y);
public static bool operator !=(MygisLineString x, MygisLineString y) => !(x == y);
public override int GetHashCode() {
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
foreach (var t in _points) ret ^= RotateShift(t.GetHashCode(), ret % sizeof(int));
return ret;
}
public bool Equals(MygisLineString other)
{
if (ReferenceEquals(other, null)) return false;
if (_points.Length != other._points.Length) return false;
for (var i = 0; i < _points.Length; i++)
if (!_points[i].Equals(other._points[i])) return false;
return true;
}
public override bool Equals(object obj) => Equals(obj as MygisLineString);
public static bool operator ==(MygisLineString x, MygisLineString y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y);
public static bool operator !=(MygisLineString x, MygisLineString y) => !(x == y);
public override int GetHashCode()
{
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
foreach (var t in _points) ret ^= RotateShift(t.GetHashCode(), ret % sizeof(int));
return ret;
}
}
public class MygisPolygon : MygisGeometry, IEquatable<MygisPolygon>, IEnumerable<IEnumerable<MygisCoordinate2D>> {
readonly MygisCoordinate2D[][] _rings;
protected override int GetLenHelper() => 4 + _rings.Length * 4 + TotalPointCount * 16;
public MygisCoordinate2D this[int ringIndex, int pointIndex] => _rings[ringIndex][pointIndex];
public MygisCoordinate2D[] this[int ringIndex] => _rings[ringIndex];
public IEnumerator<IEnumerable<MygisCoordinate2D>> GetEnumerator() => ((IEnumerable<IEnumerable<MygisCoordinate2D>>) _rings).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public int RingCount => _rings.Length;
public int TotalPointCount => _rings.Sum(r => r.Length);
public class MygisPolygon : MygisGeometry, IEquatable<MygisPolygon>, IEnumerable<IEnumerable<MygisCoordinate2D>>
{
readonly MygisCoordinate2D[][] _rings;
protected override int GetLenHelper() => 4 + _rings.Length * 4 + TotalPointCount * 16;
public MygisCoordinate2D this[int ringIndex, int pointIndex] => _rings[ringIndex][pointIndex];
public MygisCoordinate2D[] this[int ringIndex] => _rings[ringIndex];
public IEnumerator<IEnumerable<MygisCoordinate2D>> GetEnumerator() => ((IEnumerable<IEnumerable<MygisCoordinate2D>>)_rings).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public int RingCount => _rings.Length;
public int TotalPointCount => _rings.Sum(r => r.Length);
public MygisPolygon(MygisCoordinate2D[][] rings) {
_rings = rings;
}
public MygisPolygon(IEnumerable<IEnumerable<MygisCoordinate2D>> rings) {
_rings = rings.Select(x => x.ToArray()).ToArray();
}
public MygisPolygon(MygisCoordinate2D[][] rings)
{
_rings = rings;
}
public MygisPolygon(IEnumerable<IEnumerable<MygisCoordinate2D>> rings)
{
_rings = rings.Select(x => x.ToArray()).ToArray();
}
public bool Equals(MygisPolygon other) {
if (ReferenceEquals(other, null)) return false;
if (_rings.Length != other._rings.Length) return false;
for (var i = 0; i < _rings.Length; i++) {
if (_rings[i].Length != other._rings[i].Length) return false;
for (var j = 0; j < _rings[i].Length; j++)
if (!_rings[i][j].Equals(other._rings[i][j])) return false;
}
return true;
}
public override bool Equals(object obj) => Equals(obj as MygisPolygon);
public static bool operator ==(MygisPolygon x, MygisPolygon y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y);
public static bool operator !=(MygisPolygon x, MygisPolygon y) => !(x == y);
public override int GetHashCode() {
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
for (var i = 0; i < _rings.Length; i++)
for (var j = 0; j < _rings[i].Length; j++)
ret ^= RotateShift(_rings[i][j].GetHashCode(), ret % sizeof(int));
return ret;
}
public bool Equals(MygisPolygon other)
{
if (ReferenceEquals(other, null)) return false;
if (_rings.Length != other._rings.Length) return false;
for (var i = 0; i < _rings.Length; i++)
{
if (_rings[i].Length != other._rings[i].Length) return false;
for (var j = 0; j < _rings[i].Length; j++)
if (!_rings[i][j].Equals(other._rings[i][j])) return false;
}
return true;
}
public override bool Equals(object obj) => Equals(obj as MygisPolygon);
public static bool operator ==(MygisPolygon x, MygisPolygon y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y);
public static bool operator !=(MygisPolygon x, MygisPolygon y) => !(x == y);
public override int GetHashCode()
{
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
for (var i = 0; i < _rings.Length; i++)
for (var j = 0; j < _rings[i].Length; j++)
ret ^= RotateShift(_rings[i][j].GetHashCode(), ret % sizeof(int));
return ret;
}
}
public class MygisMultiPoint : MygisGeometry, IEquatable<MygisMultiPoint>, IEnumerable<MygisCoordinate2D> {
readonly MygisCoordinate2D[] _points;
protected override int GetLenHelper() => 4 + _points.Length * 21;
public IEnumerator<MygisCoordinate2D> GetEnumerator() => ((IEnumerable<MygisCoordinate2D>) _points).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public MygisCoordinate2D this[int indexer] => _points[indexer];
public int PointCount => _points.Length;
public class MygisMultiPoint : MygisGeometry, IEquatable<MygisMultiPoint>, IEnumerable<MygisCoordinate2D>
{
readonly MygisCoordinate2D[] _points;
protected override int GetLenHelper() => 4 + _points.Length * 21;
public IEnumerator<MygisCoordinate2D> GetEnumerator() => ((IEnumerable<MygisCoordinate2D>)_points).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public MygisCoordinate2D this[int indexer] => _points[indexer];
public int PointCount => _points.Length;
public MygisMultiPoint(MygisCoordinate2D[] points) {
_points = points;
}
public MygisMultiPoint(IEnumerable<MygisPoint> points) {
_points = points.Select(x => new MygisCoordinate2D(x.X, x.Y)).ToArray();
}
public MygisMultiPoint(IEnumerable<MygisCoordinate2D> points) {
_points = points.ToArray();
}
public MygisMultiPoint(MygisCoordinate2D[] points)
{
_points = points;
}
public MygisMultiPoint(IEnumerable<MygisPoint> points)
{
_points = points.Select(x => new MygisCoordinate2D(x.X, x.Y)).ToArray();
}
public MygisMultiPoint(IEnumerable<MygisCoordinate2D> points)
{
_points = points.ToArray();
}
public bool Equals(MygisMultiPoint other) {
if (ReferenceEquals(other, null)) return false;
if (_points.Length != other._points.Length) return false;
for (var i = 0; i < _points.Length; i++)
if (!_points[i].Equals(other._points[i])) return false;
return true;
}
public override bool Equals(object obj) => Equals(obj as MygisMultiPoint);
public static bool operator ==(MygisMultiPoint x, MygisMultiPoint y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y);
public static bool operator !=(MygisMultiPoint x, MygisMultiPoint y) => !(x == y);
public override int GetHashCode() {
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
for (var i = 0; i < _points.Length; i++) ret ^= RotateShift(_points[i].GetHashCode(), ret % sizeof(int));
return ret;
}
public bool Equals(MygisMultiPoint other)
{
if (ReferenceEquals(other, null)) return false;
if (_points.Length != other._points.Length) return false;
for (var i = 0; i < _points.Length; i++)
if (!_points[i].Equals(other._points[i])) return false;
return true;
}
public override bool Equals(object obj) => Equals(obj as MygisMultiPoint);
public static bool operator ==(MygisMultiPoint x, MygisMultiPoint y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y);
public static bool operator !=(MygisMultiPoint x, MygisMultiPoint y) => !(x == y);
public override int GetHashCode()
{
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
for (var i = 0; i < _points.Length; i++) ret ^= RotateShift(_points[i].GetHashCode(), ret % sizeof(int));
return ret;
}
}
public sealed class MygisMultiLineString : MygisGeometry,
IEquatable<MygisMultiLineString>, IEnumerable<MygisLineString> {
readonly MygisLineString[] _lineStrings;
protected override int GetLenHelper() {
var n = 4;
for (var i = 0; i < _lineStrings.Length; i++) n += _lineStrings[i].GetLen(false);
return n;
}
public IEnumerator<MygisLineString> GetEnumerator() => ((IEnumerable<MygisLineString>) _lineStrings).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public MygisLineString this[int index] => _lineStrings[index];
public int LineCount => _lineStrings.Length;
IEquatable<MygisMultiLineString>, IEnumerable<MygisLineString>
{
readonly MygisLineString[] _lineStrings;
protected override int GetLenHelper()
{
var n = 4;
for (var i = 0; i < _lineStrings.Length; i++) n += _lineStrings[i].GetLen(false);
return n;
}
public IEnumerator<MygisLineString> GetEnumerator() => ((IEnumerable<MygisLineString>)_lineStrings).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public MygisLineString this[int index] => _lineStrings[index];
public int LineCount => _lineStrings.Length;
internal MygisMultiLineString(MygisCoordinate2D[][] pointArray) {
_lineStrings = new MygisLineString[pointArray.Length];
for (var i = 0; i < pointArray.Length; i++)
_lineStrings[i] = new MygisLineString(pointArray[i]);
}
public MygisMultiLineString(MygisLineString[] linestrings) {
_lineStrings = linestrings;
}
public MygisMultiLineString(IEnumerable<MygisLineString> linestrings) {
_lineStrings = linestrings.ToArray();
}
public MygisMultiLineString(IEnumerable<IEnumerable<MygisCoordinate2D>> pointList) {
_lineStrings = pointList.Select(x => new MygisLineString(x)).ToArray();
}
internal MygisMultiLineString(MygisCoordinate2D[][] pointArray)
{
_lineStrings = new MygisLineString[pointArray.Length];
for (var i = 0; i < pointArray.Length; i++)
_lineStrings[i] = new MygisLineString(pointArray[i]);
}
public MygisMultiLineString(MygisLineString[] linestrings)
{
_lineStrings = linestrings;
}
public MygisMultiLineString(IEnumerable<MygisLineString> linestrings)
{
_lineStrings = linestrings.ToArray();
}
public MygisMultiLineString(IEnumerable<IEnumerable<MygisCoordinate2D>> pointList)
{
_lineStrings = pointList.Select(x => new MygisLineString(x)).ToArray();
}
public bool Equals(MygisMultiLineString other) {
if (ReferenceEquals(other, null)) return false;
if (_lineStrings.Length != other._lineStrings.Length) return false;
for (var i = 0; i < _lineStrings.Length; i++)
if (_lineStrings[i] != other._lineStrings[i]) return false;
return true;
}
public override bool Equals(object obj) => Equals(obj as MygisMultiLineString);
public static bool operator ==(MygisMultiLineString x, MygisMultiLineString y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y);
public static bool operator !=(MygisMultiLineString x, MygisMultiLineString y) => !(x == y);
public override int GetHashCode() {
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
for (var i = 0; i < _lineStrings.Length; i++) ret ^= RotateShift(_lineStrings[i].GetHashCode(), ret % sizeof(int));
return ret;
}
public bool Equals(MygisMultiLineString other)
{
if (ReferenceEquals(other, null)) return false;
if (_lineStrings.Length != other._lineStrings.Length) return false;
for (var i = 0; i < _lineStrings.Length; i++)
if (_lineStrings[i] != other._lineStrings[i]) return false;
return true;
}
public override bool Equals(object obj) => Equals(obj as MygisMultiLineString);
public static bool operator ==(MygisMultiLineString x, MygisMultiLineString y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y);
public static bool operator !=(MygisMultiLineString x, MygisMultiLineString y) => !(x == y);
public override int GetHashCode()
{
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
for (var i = 0; i < _lineStrings.Length; i++) ret ^= RotateShift(_lineStrings[i].GetHashCode(), ret % sizeof(int));
return ret;
}
}
public class MygisMultiPolygon : MygisGeometry, IEquatable<MygisMultiPolygon>, IEnumerable<MygisPolygon> {
readonly MygisPolygon[] _polygons;
protected override int GetLenHelper() {
var n = 4;
for (var i = 0; i < _polygons.Length; i++) n += _polygons[i].GetLen(false);
return n;
}
public IEnumerator<MygisPolygon> GetEnumerator() => ((IEnumerable<MygisPolygon>) _polygons).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public MygisPolygon this[int index] => _polygons[index];
public int PolygonCount => _polygons.Length;
public class MygisMultiPolygon : MygisGeometry, IEquatable<MygisMultiPolygon>, IEnumerable<MygisPolygon>
{
readonly MygisPolygon[] _polygons;
protected override int GetLenHelper()
{
var n = 4;
for (var i = 0; i < _polygons.Length; i++) n += _polygons[i].GetLen(false);
return n;
}
public IEnumerator<MygisPolygon> GetEnumerator() => ((IEnumerable<MygisPolygon>)_polygons).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public MygisPolygon this[int index] => _polygons[index];
public int PolygonCount => _polygons.Length;
public MygisMultiPolygon(MygisPolygon[] polygons) {
_polygons = polygons;
}
public MygisMultiPolygon(IEnumerable<MygisPolygon> polygons) {
_polygons = polygons.ToArray();
}
public MygisMultiPolygon(IEnumerable<IEnumerable<IEnumerable<MygisCoordinate2D>>> ringList) {
_polygons = ringList.Select(x => new MygisPolygon(x)).ToArray();
}
public MygisMultiPolygon(MygisPolygon[] polygons)
{
_polygons = polygons;
}
public MygisMultiPolygon(IEnumerable<MygisPolygon> polygons)
{
_polygons = polygons.ToArray();
}
public MygisMultiPolygon(IEnumerable<IEnumerable<IEnumerable<MygisCoordinate2D>>> ringList)
{
_polygons = ringList.Select(x => new MygisPolygon(x)).ToArray();
}
public bool Equals(MygisMultiPolygon other) {
if (ReferenceEquals(other, null)) return false;
if (_polygons.Length != other._polygons.Length) return false;
for (var i = 0; i < _polygons.Length; i++) if (_polygons[i] != other._polygons[i]) return false;
return true;
}
public override bool Equals(object obj) => obj is MygisMultiPolygon && Equals((MygisMultiPolygon) obj);
public static bool operator ==(MygisMultiPolygon x, MygisMultiPolygon y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y);
public static bool operator !=(MygisMultiPolygon x, MygisMultiPolygon y) => !(x == y);
public override int GetHashCode() {
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
for (var i = 0; i < _polygons.Length; i++) ret ^= RotateShift(_polygons[i].GetHashCode(), ret % sizeof(int));
return ret;
}
public bool Equals(MygisMultiPolygon other)
{
if (ReferenceEquals(other, null)) return false;
if (_polygons.Length != other._polygons.Length) return false;
for (var i = 0; i < _polygons.Length; i++) if (_polygons[i] != other._polygons[i]) return false;
return true;
}
public override bool Equals(object obj) => obj is MygisMultiPolygon && Equals((MygisMultiPolygon)obj);
public static bool operator ==(MygisMultiPolygon x, MygisMultiPolygon y) => ReferenceEquals(x, null) ? ReferenceEquals(y, null) : x.Equals(y);
public static bool operator !=(MygisMultiPolygon x, MygisMultiPolygon y) => !(x == y);
public override int GetHashCode()
{
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
for (var i = 0; i < _polygons.Length; i++) ret ^= RotateShift(_polygons[i].GetHashCode(), ret % sizeof(int));
return ret;
}
}

View File

@ -6,18 +6,20 @@ using System.Drawing;
using System.Reflection;
using System.Text;
public static partial class MygisTypesExtensions {
/// <summary>
/// 测量两个经纬度的距离,返回单位:米
/// </summary>
/// <param name="that">经纬坐标1</param>
/// <param name="point">经纬坐标2</param>
/// <returns>返回距离(单位:米)</returns>
public static double Distance(this MygisPoint that, MygisPoint point) {
double radLat1 = (double)(that.Y) * Math.PI / 180d;
double radLng1 = (double)(that.X) * Math.PI / 180d;
double radLat2 = (double)(point.Y) * Math.PI / 180d;
double radLng2 = (double)(point.X) * Math.PI / 180d;
return 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin((radLat1 - radLat2) / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin((radLng1 - radLng2) / 2), 2))) * 6378137;
}
public static partial class MygisTypesExtensions
{
/// <summary>
/// 测量两个经纬度的距离,返回单位:米
/// </summary>
/// <param name="that">经纬坐标1</param>
/// <param name="point">经纬坐标2</param>
/// <returns>返回距离(单位:米)</returns>
public static double Distance(this MygisPoint that, MygisPoint point)
{
double radLat1 = (double)(that.Y) * Math.PI / 180d;
double radLng1 = (double)(that.X) * Math.PI / 180d;
double radLat2 = (double)(point.Y) * Math.PI / 180d;
double radLng2 = (double)(point.X) * Math.PI / 180d;
return 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin((radLat1 - radLat2) / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin((radLng1 - radLng2) / 2), 2))) * 6378137;
}
}

View File

@ -11,143 +11,165 @@ using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace FreeSql.MySql {
namespace FreeSql.MySql
{
class MySqlCodeFirst : Internal.CommonProvider.CodeFirstProvider {
class MySqlCodeFirst : Internal.CommonProvider.CodeFirstProvider
{
public MySqlCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { }
public MySqlCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { }
static object _dicCsToDbLock = new object();
static Dictionary<string, (MySqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (MySqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
{ typeof(bool).FullName, (MySqlDbType.Bit, "bit","bit(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (MySqlDbType.Bit, "bit","bit(1)", null, true, null) },
static object _dicCsToDbLock = new object();
static Dictionary<string, (MySqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (MySqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
{ typeof(bool).FullName, (MySqlDbType.Bit, "bit","bit(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, (MySqlDbType.Bit, "bit","bit(1)", null, true, null) },
{ typeof(sbyte).FullName, (MySqlDbType.Byte, "tinyint", "tinyint(3) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (MySqlDbType.Byte, "tinyint", "tinyint(3)", false, true, null) },
{ typeof(short).FullName, (MySqlDbType.Int16, "smallint","smallint(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (MySqlDbType.Int16, "smallint", "smallint(6)", false, true, null) },
{ typeof(int).FullName, (MySqlDbType.Int32, "int", "int(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (MySqlDbType.Int32, "int", "int(11)", false, true, null) },
{ typeof(long).FullName, (MySqlDbType.Int64, "bigint","bigint(20) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (MySqlDbType.Int64, "bigint","bigint(20)", false, true, null) },
{ typeof(sbyte).FullName, (MySqlDbType.Byte, "tinyint", "tinyint(3) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (MySqlDbType.Byte, "tinyint", "tinyint(3)", false, true, null) },
{ typeof(short).FullName, (MySqlDbType.Int16, "smallint","smallint(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, (MySqlDbType.Int16, "smallint", "smallint(6)", false, true, null) },
{ typeof(int).FullName, (MySqlDbType.Int32, "int", "int(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, (MySqlDbType.Int32, "int", "int(11)", false, true, null) },
{ typeof(long).FullName, (MySqlDbType.Int64, "bigint","bigint(20) NOT NULL", false, false, 0) },{ typeof(long?).FullName, (MySqlDbType.Int64, "bigint","bigint(20)", false, true, null) },
{ typeof(byte).FullName, (MySqlDbType.UByte, "tinyint","tinyint(3) unsigned NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (MySqlDbType.UByte, "tinyint","tinyint(3) unsigned", true, true, null) },
{ typeof(ushort).FullName, (MySqlDbType.UInt16, "smallint","smallint(5) unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (MySqlDbType.UInt16, "smallint", "smallint(5) unsigned", true, true, null) },
{ typeof(uint).FullName, (MySqlDbType.UInt32, "int", "int(10) unsigned NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (MySqlDbType.UInt32, "int", "int(10) unsigned", true, true, null) },
{ typeof(ulong).FullName, (MySqlDbType.UInt64, "bigint", "bigint(20) unsigned NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (MySqlDbType.UInt64, "bigint", "bigint(20) unsigned", true, true, null) },
{ typeof(byte).FullName, (MySqlDbType.UByte, "tinyint","tinyint(3) unsigned NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (MySqlDbType.UByte, "tinyint","tinyint(3) unsigned", true, true, null) },
{ typeof(ushort).FullName, (MySqlDbType.UInt16, "smallint","smallint(5) unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (MySqlDbType.UInt16, "smallint", "smallint(5) unsigned", true, true, null) },
{ typeof(uint).FullName, (MySqlDbType.UInt32, "int", "int(10) unsigned NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (MySqlDbType.UInt32, "int", "int(10) unsigned", true, true, null) },
{ typeof(ulong).FullName, (MySqlDbType.UInt64, "bigint", "bigint(20) unsigned NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (MySqlDbType.UInt64, "bigint", "bigint(20) unsigned", true, true, null) },
{ typeof(double).FullName, (MySqlDbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (MySqlDbType.Double, "double", "double", false, true, null) },
{ typeof(float).FullName, (MySqlDbType.Float, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, (MySqlDbType.Float, "float","float", false, true, null) },
{ typeof(decimal).FullName, (MySqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (MySqlDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) },
{ typeof(double).FullName, (MySqlDbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, (MySqlDbType.Double, "double", "double", false, true, null) },
{ typeof(float).FullName, (MySqlDbType.Float, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, (MySqlDbType.Float, "float","float", false, true, null) },
{ typeof(decimal).FullName, (MySqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (MySqlDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) },
{ typeof(TimeSpan).FullName, (MySqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (MySqlDbType.Time, "time", "time",false, true, null) },
{ typeof(DateTime).FullName, (MySqlDbType.DateTime, "datetime(3)", "datetime(3) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (MySqlDbType.DateTime, "datetime(3)", "datetime(3)", false, true, null) },
{ typeof(TimeSpan).FullName, (MySqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (MySqlDbType.Time, "time", "time",false, true, null) },
{ typeof(DateTime).FullName, (MySqlDbType.DateTime, "datetime(3)", "datetime(3) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (MySqlDbType.DateTime, "datetime(3)", "datetime(3)", false, true, null) },
{ typeof(byte[]).FullName, (MySqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) },
{ typeof(string).FullName, (MySqlDbType.VarChar, "varchar", "varchar(255)", false, null, "") },
{ typeof(byte[]).FullName, (MySqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) },
{ typeof(string).FullName, (MySqlDbType.VarChar, "varchar", "varchar(255)", false, null, "") },
{ typeof(Guid).FullName, (MySqlDbType.VarChar, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (MySqlDbType.VarChar, "char", "char(36)", false, true, null) },
{ typeof(Guid).FullName, (MySqlDbType.VarChar, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (MySqlDbType.VarChar, "char", "char(36)", false, true, null) },
{ typeof(MygisPoint).FullName, (MySqlDbType.Geometry, "point", "point", false, null, new MygisPoint(0, 0)) },
{ typeof(MygisLineString).FullName, (MySqlDbType.Geometry, "linestring", "linestring", false, null, new MygisLineString(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) },
{ typeof(MygisPolygon).FullName, (MySqlDbType.Geometry, "polygon", "polygon", false, null, new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})) },
{ typeof(MygisMultiPoint).FullName, (MySqlDbType.Geometry, "multipoint","multipoint", false, null, new MygisMultiPoint(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) },
{ typeof(MygisMultiLineString).FullName, (MySqlDbType.Geometry, "multilinestring","multilinestring", false, null, new MygisMultiLineString(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})) },
{ typeof(MygisMultiPolygon).FullName, (MySqlDbType.Geometry, "multipolygon", "multipolygon", false, null, new MygisMultiPolygon(new[]{new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}}),new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})})) },
};
{ typeof(MygisPoint).FullName, (MySqlDbType.Geometry, "point", "point", false, null, new MygisPoint(0, 0)) },
{ typeof(MygisLineString).FullName, (MySqlDbType.Geometry, "linestring", "linestring", false, null, new MygisLineString(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) },
{ typeof(MygisPolygon).FullName, (MySqlDbType.Geometry, "polygon", "polygon", false, null, new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})) },
{ typeof(MygisMultiPoint).FullName, (MySqlDbType.Geometry, "multipoint","multipoint", false, null, new MygisMultiPoint(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) },
{ typeof(MygisMultiLineString).FullName, (MySqlDbType.Geometry, "multilinestring","multilinestring", false, null, new MygisMultiLineString(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})) },
{ typeof(MygisMultiPolygon).FullName, (MySqlDbType.Geometry, "multipolygon", "multipolygon", false, null, new MygisMultiPolygon(new[]{new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}}),new MygisPolygon(new[]{new[]{new MygisCoordinate2D(),new MygisCoordinate2D()},new[]{new MygisCoordinate2D(),new MygisCoordinate2D()}})})) },
};
public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) {
if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue));
if (type.IsArray) return null;
var enumType = type.IsEnum ? type : null;
if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First();
if (enumType != null) {
var names = string.Join(",", Enum.GetNames(enumType).Select(a => _commonUtils.FormatSql("{0}", a)));
var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ?
(MySqlDbType.Set, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) :
(MySqlDbType.Enum, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0));
if (_dicCsToDb.ContainsKey(type.FullName) == false) {
lock (_dicCsToDbLock) {
if (_dicCsToDb.ContainsKey(type.FullName) == false)
_dicCsToDb.Add(type.FullName, newItem);
}
}
return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6);
}
return null;
}
public override (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type)
{
if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?, object)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue));
if (type.IsArray) return null;
var enumType = type.IsEnum ? type : null;
if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First();
if (enumType != null)
{
var names = string.Join(",", Enum.GetNames(enumType).Select(a => _commonUtils.FormatSql("{0}", a)));
var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ?
(MySqlDbType.Set, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) :
(MySqlDbType.Enum, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0));
if (_dicCsToDb.ContainsKey(type.FullName) == false)
{
lock (_dicCsToDbLock)
{
if (_dicCsToDb.ContainsKey(type.FullName) == false)
_dicCsToDb.Add(type.FullName, newItem);
}
}
return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6);
}
return null;
}
public override string GetComparisonDDLStatements(params Type[] entityTypes) {
var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5));
var database = conn.Value.Database;
Func<string, string, object> ExecuteScalar = (db, sql) => {
if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db);
try {
using (var cmd = conn.Value.CreateCommand()) {
cmd.CommandText = sql;
cmd.CommandType = CommandType.Text;
return cmd.ExecuteScalar();
}
} finally {
if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database);
}
};
var sb = new StringBuilder();
try {
foreach (var entityType in entityTypes) {
if (sb.Length > 0) sb.Append("\r\n");
var tb = _commonUtils.GetTableByEntity(entityType);
if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移");
if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移可迁移属性0个");
var tbname = tb.DbName.Split(new[] { '.' }, 2);
if (tbname?.Length == 1) tbname = new[] { database, tbname[0] };
public override string GetComparisonDDLStatements(params Type[] entityTypes)
{
var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5));
var database = conn.Value.Database;
Func<string, string, object> ExecuteScalar = (db, sql) =>
{
if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db);
try
{
using (var cmd = conn.Value.CreateCommand())
{
cmd.CommandText = sql;
cmd.CommandType = CommandType.Text;
return cmd.ExecuteScalar();
}
}
finally
{
if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database);
}
};
var sb = new StringBuilder();
try
{
foreach (var entityType in entityTypes)
{
if (sb.Length > 0) sb.Append("\r\n");
var tb = _commonUtils.GetTableByEntity(entityType);
if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移");
if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移可迁移属性0个");
var tbname = tb.DbName.Split(new[] { '.' }, 2);
if (tbname?.Length == 1) tbname = new[] { database, tbname[0] };
var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名
if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] };
var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名
if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] };
if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库
sb.Append($"CREATE DATABASE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(" default charset utf8 COLLATE utf8_general_ci;\r\n");
if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库
sb.Append($"CREATE DATABASE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(" default charset utf8 COLLATE utf8_general_ci;\r\n");
var sbalter = new StringBuilder();
var istmpatler = false; //创建临时表,导入数据,删除旧表,修改
if (ExecuteScalar(tbname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tbname)) == null) { //表不存在
if (tboldname != null) {
if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tboldname[0])) == null ||
ExecuteScalar(tboldname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tboldname)) == null)
//数据库或表不存在
tboldname = null;
}
if (tboldname == null) {
//创建表
sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( ");
foreach (var tbcol in tb.Columns.Values) {
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ");
sb.Append(tbcol.Attribute.DbType);
if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT");
if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment));
sb.Append(",");
}
if (tb.Primarys.Any()) {
sb.Append(" \r\n PRIMARY KEY (");
foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
foreach (var uk in tb.Uniques) {
sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("(");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("\r\n) Engine=InnoDB;\r\n");
continue;
}
//如果新表,旧表在一个数据库下,直接修改表名
if (string.Compare(tbname[0], tboldname[0], true) == 0)
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n");
else {
//如果新表,旧表不在一起,创建新表,导入数据,删除旧表
istmpatler = true;
}
} else
tboldname = null; //如果新表已经存在,不走改表名逻辑
var sbalter = new StringBuilder();
var istmpatler = false; //创建临时表,导入数据,删除旧表,修改
if (ExecuteScalar(tbname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tbname)) == null)
{ //表不存在
if (tboldname != null)
{
if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tboldname[0])) == null ||
ExecuteScalar(tboldname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tboldname)) == null)
//数据库或表不存在
tboldname = null;
}
if (tboldname == null)
{
//创建表
sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ( ");
foreach (var tbcol in tb.Columns.Values)
{
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ");
sb.Append(tbcol.Attribute.DbType);
if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT");
if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment));
sb.Append(",");
}
if (tb.Primarys.Any())
{
sb.Append(" \r\n PRIMARY KEY (");
foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
foreach (var uk in tb.Uniques)
{
sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("(");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("\r\n) Engine=InnoDB;\r\n");
continue;
}
//如果新表,旧表在一个数据库下,直接修改表名
if (string.Compare(tbname[0], tboldname[0], true) == 0)
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n");
else
{
//如果新表,旧表不在一起,创建新表,导入数据,删除旧表
istmpatler = true;
}
}
else
tboldname = null; //如果新表已经存在,不走改表名逻辑
//对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段
var sql = _commonUtils.FormatSql(@"
//对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段
var sql = _commonUtils.FormatSql(@"
select
a.column_name,
a.column_type,
@ -156,131 +178,153 @@ case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity',
a.column_comment 'comment'
from information_schema.columns a
where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname);
var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => {
var a1 = string.Concat(a[1]);
if (a1 == "datetime") a1 = string.Concat(a1, "(0)");
return new {
column = string.Concat(a[0]),
sqlType = a1,
is_nullable = string.Concat(a[2]) == "1",
is_identity = string.Concat(a[3]) == "1",
is_unsigned = string.Concat(a[1]).EndsWith(" unsigned"),
comment = string.Concat(a[4])
};
}, StringComparer.CurrentCultureIgnoreCase);
var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a =>
{
var a1 = string.Concat(a[1]);
if (a1 == "datetime") a1 = string.Concat(a1, "(0)");
return new
{
column = string.Concat(a[0]),
sqlType = a1,
is_nullable = string.Concat(a[2]) == "1",
is_identity = string.Concat(a[3]) == "1",
is_unsigned = string.Concat(a[1]).EndsWith(" unsigned"),
comment = string.Concat(a[4])
};
}, StringComparer.CurrentCultureIgnoreCase);
if (istmpatler == false) {
var existsPrimary = ExecuteScalar(tbname[0], _commonUtils.FormatSql("select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname));
foreach (var tbcol in tb.Columns.Values) {
var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1;
if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) ||
string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) {
var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? "");
if ((tbcol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != tbstructcol.is_unsigned ||
tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false ||
tbcol.Attribute.IsNullable != tbstructcol.is_nullable ||
tbcol.Attribute.IsIdentity != tbstructcol.is_identity ||
isCommentChanged) {
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType);
if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? ""));
if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(")");
sbalter.Append(";\r\n");
}
if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) {
//修改列名
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType);
if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? ""));
if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")");
sbalter.Append(";\r\n");
}
continue;
}
//添加列
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType);
if (tbcol.Attribute.IsNullable == false) sbalter.Append(" DEFAULT ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue));
if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? ""));
if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")");
sbalter.Append(";\r\n");
}
var dsuksql = _commonUtils.FormatSql(@"
if (istmpatler == false)
{
var existsPrimary = ExecuteScalar(tbname[0], _commonUtils.FormatSql("select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname));
foreach (var tbcol in tb.Columns.Values)
{
var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1;
if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) ||
string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol))
{
var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? "");
if ((tbcol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != tbstructcol.is_unsigned ||
tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false ||
tbcol.Attribute.IsNullable != tbstructcol.is_nullable ||
tbcol.Attribute.IsIdentity != tbstructcol.is_identity ||
isCommentChanged)
{
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType);
if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? ""));
if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(")");
sbalter.Append(";\r\n");
}
if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0)
{
//修改列名
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType);
if (isCommentChanged) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? ""));
if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")");
sbalter.Append(";\r\n");
}
continue;
}
//添加列
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType);
if (tbcol.Attribute.IsNullable == false) sbalter.Append(" DEFAULT ").Append(_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue));
if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? ""));
if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")");
sbalter.Append(";\r\n");
}
var dsuksql = _commonUtils.FormatSql(@"
select
a.column_name,
a.constraint_name 'index_id'
from information_schema.key_column_usage a
where a.constraint_schema IN ({0}) and a.table_name IN ({1})", tboldname ?? tbname);
var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) });
foreach (var uk in tb.Uniques) {
if (uk.Key == "PRIMARY" || string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue;
var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray();
if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) {
if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n");
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE(");
foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n");
}
}
}
if (istmpatler == false) {
sb.Append(sbalter);
continue;
}
var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) });
foreach (var uk in tb.Uniques)
{
if (uk.Key == "PRIMARY" || string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue;
var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray();
if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count)
{
if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n");
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE(");
foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n");
}
}
}
if (istmpatler == false)
{
sb.Append(sbalter);
continue;
}
//创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名
var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}");
var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}");
//创建临时表
sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( ");
foreach (var tbcol in tb.Columns.Values) {
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ");
sb.Append(tbcol.Attribute.DbType);
if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT");
if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment));
sb.Append(",");
}
if (tb.Primarys.Any()) {
sb.Append(" \r\n PRIMARY KEY (");
foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
foreach (var uk in tb.Uniques) {
sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("(");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("\r\n) Engine=InnoDB;\r\n");
sb.Append("INSERT INTO ").Append(tmptablename).Append(" (");
foreach (var tbcol in tb.Columns.Values)
sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT ");
foreach (var tbcol in tb.Columns.Values) {
var insertvalue = "NULL";
if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) ||
string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) {
insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column);
if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) {
//insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})";
}
if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable)
insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})";
} else if (tbcol.Attribute.IsNullable == false)
insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue);
sb.Append(insertvalue).Append(", ");
}
sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n");
sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n");
sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n");
}
return sb.Length == 0 ? null : sb.ToString();
} finally {
try {
conn.Value.ChangeDatabase(database);
_orm.Ado.MasterPool.Return(conn);
} catch {
_orm.Ado.MasterPool.Return(conn, true);
}
}
}
}
//创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名
var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}");
var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}");
//创建临时表
sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ( ");
foreach (var tbcol in tb.Columns.Values)
{
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ");
sb.Append(tbcol.Attribute.DbType);
if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT");
if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment));
sb.Append(",");
}
if (tb.Primarys.Any())
{
sb.Append(" \r\n PRIMARY KEY (");
foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
foreach (var uk in tb.Uniques)
{
sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("(");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("\r\n) Engine=InnoDB;\r\n");
sb.Append("INSERT INTO ").Append(tmptablename).Append(" (");
foreach (var tbcol in tb.Columns.Values)
sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT ");
foreach (var tbcol in tb.Columns.Values)
{
var insertvalue = "NULL";
if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) ||
string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol))
{
insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column);
if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false)
{
//insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})";
}
if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable)
insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})";
}
else if (tbcol.Attribute.IsNullable == false)
insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue);
sb.Append(insertvalue).Append(", ");
}
sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n");
sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n");
sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n");
}
return sb.Length == 0 ? null : sb.ToString();
}
finally
{
try
{
conn.Value.ChangeDatabase(database);
_orm.Ado.MasterPool.Return(conn);
}
catch
{
_orm.Ado.MasterPool.Return(conn, true);
}
}
}
}
}

View File

@ -7,149 +7,158 @@ using System.Data;
using System.Linq;
using System.Text.RegularExpressions;
namespace FreeSql.MySql {
class MySqlDbFirst : IDbFirst {
IFreeSql _orm;
protected CommonUtils _commonUtils;
protected CommonExpression _commonExpression;
public MySqlDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) {
_orm = orm;
_commonUtils = commonUtils;
_commonExpression = commonExpression;
}
namespace FreeSql.MySql
{
class MySqlDbFirst : IDbFirst
{
IFreeSql _orm;
protected CommonUtils _commonUtils;
protected CommonExpression _commonExpression;
public MySqlDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression)
{
_orm = orm;
_commonUtils = commonUtils;
_commonExpression = commonExpression;
}
public int GetDbType(DbColumnInfo column) => (int)GetMySqlDbType(column);
MySqlDbType GetMySqlDbType(DbColumnInfo column) {
var is_unsigned = column.DbTypeTextFull.ToLower().EndsWith(" unsigned");
switch (column.DbTypeText.ToLower()) {
case "bit": return MySqlDbType.Bit;
public int GetDbType(DbColumnInfo column) => (int)GetMySqlDbType(column);
MySqlDbType GetMySqlDbType(DbColumnInfo column)
{
var is_unsigned = column.DbTypeTextFull.ToLower().EndsWith(" unsigned");
switch (column.DbTypeText.ToLower())
{
case "bit": return MySqlDbType.Bit;
case "tinyint": return is_unsigned ? MySqlDbType.UByte : MySqlDbType.Byte;
case "smallint": return is_unsigned ? MySqlDbType.UInt16 : MySqlDbType.Int16;
case "mediumint": return is_unsigned ? MySqlDbType.UInt24 : MySqlDbType.Int24;
case "int": return is_unsigned ? MySqlDbType.UInt32 : MySqlDbType.Int32;
case "bigint": return is_unsigned ? MySqlDbType.UInt64 : MySqlDbType.Int64;
case "tinyint": return is_unsigned ? MySqlDbType.UByte : MySqlDbType.Byte;
case "smallint": return is_unsigned ? MySqlDbType.UInt16 : MySqlDbType.Int16;
case "mediumint": return is_unsigned ? MySqlDbType.UInt24 : MySqlDbType.Int24;
case "int": return is_unsigned ? MySqlDbType.UInt32 : MySqlDbType.Int32;
case "bigint": return is_unsigned ? MySqlDbType.UInt64 : MySqlDbType.Int64;
case "real":
case "double": return MySqlDbType.Double;
case "float": return MySqlDbType.Float;
case "numeric":
case "decimal": return MySqlDbType.Decimal;
case "real":
case "double": return MySqlDbType.Double;
case "float": return MySqlDbType.Float;
case "numeric":
case "decimal": return MySqlDbType.Decimal;
case "year": return MySqlDbType.Year;
case "time": return MySqlDbType.Time;
case "date": return MySqlDbType.Date;
case "timestamp": return MySqlDbType.Timestamp;
case "datetime": return MySqlDbType.DateTime;
case "year": return MySqlDbType.Year;
case "time": return MySqlDbType.Time;
case "date": return MySqlDbType.Date;
case "timestamp": return MySqlDbType.Timestamp;
case "datetime": return MySqlDbType.DateTime;
case "tinyblob": return MySqlDbType.TinyBlob;
case "blob": return MySqlDbType.Blob;
case "mediumblob": return MySqlDbType.MediumBlob;
case "longblob": return MySqlDbType.LongBlob;
case "tinyblob": return MySqlDbType.TinyBlob;
case "blob": return MySqlDbType.Blob;
case "mediumblob": return MySqlDbType.MediumBlob;
case "longblob": return MySqlDbType.LongBlob;
case "binary": return MySqlDbType.Binary;
case "varbinary": return MySqlDbType.VarBinary;
case "binary": return MySqlDbType.Binary;
case "varbinary": return MySqlDbType.VarBinary;
case "tinytext": return MySqlDbType.TinyText;
case "text": return MySqlDbType.Text;
case "mediumtext": return MySqlDbType.MediumText;
case "longtext": return MySqlDbType.LongText;
case "tinytext": return MySqlDbType.TinyText;
case "text": return MySqlDbType.Text;
case "mediumtext": return MySqlDbType.MediumText;
case "longtext": return MySqlDbType.LongText;
case "char": return column.MaxLength == 36 ? MySqlDbType.Guid : MySqlDbType.String;
case "varchar": return MySqlDbType.VarChar;
case "char": return column.MaxLength == 36 ? MySqlDbType.Guid : MySqlDbType.String;
case "varchar": return MySqlDbType.VarChar;
case "set": return MySqlDbType.Set;
case "enum": return MySqlDbType.Enum;
case "set": return MySqlDbType.Set;
case "enum": return MySqlDbType.Enum;
case "point": return MySqlDbType.Geometry;
case "linestring": return MySqlDbType.Geometry;
case "polygon": return MySqlDbType.Geometry;
case "geometry": return MySqlDbType.Geometry;
case "multipoint": return MySqlDbType.Geometry;
case "multilinestring": return MySqlDbType.Geometry;
case "multipolygon": return MySqlDbType.Geometry;
case "geometrycollection": return MySqlDbType.Geometry;
default: return MySqlDbType.String;
}
}
case "point": return MySqlDbType.Geometry;
case "linestring": return MySqlDbType.Geometry;
case "polygon": return MySqlDbType.Geometry;
case "geometry": return MySqlDbType.Geometry;
case "multipoint": return MySqlDbType.Geometry;
case "multilinestring": return MySqlDbType.Geometry;
case "multipolygon": return MySqlDbType.Geometry;
case "geometrycollection": return MySqlDbType.Geometry;
default: return MySqlDbType.String;
}
}
static readonly Dictionary<int, (string csConvert, string csParse, string csStringify, string csType, Type csTypeInfo, Type csNullableTypeInfo, string csTypeValue, string dataReaderMethod)> _dicDbToCs = new Dictionary<int, (string csConvert, string csParse, string csStringify, string csType, Type csTypeInfo, Type csNullableTypeInfo, string csTypeValue, string dataReaderMethod)>() {
{ (int)MySqlDbType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") },
static readonly Dictionary<int, (string csConvert, string csParse, string csStringify, string csType, Type csTypeInfo, Type csNullableTypeInfo, string csTypeValue, string dataReaderMethod)> _dicDbToCs = new Dictionary<int, (string csConvert, string csParse, string csStringify, string csType, Type csTypeInfo, Type csNullableTypeInfo, string csTypeValue, string dataReaderMethod)>() {
{ (int)MySqlDbType.Bit, ("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") },
{ (int)MySqlDbType.Byte, ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetByte") },
{ (int)MySqlDbType.Int16, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") },
{ (int)MySqlDbType.Int24, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") },
{ (int)MySqlDbType.Int32, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") },
{ (int)MySqlDbType.Int64, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") },
{ (int)MySqlDbType.Byte, ("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetByte") },
{ (int)MySqlDbType.Int16, ("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") },
{ (int)MySqlDbType.Int24, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") },
{ (int)MySqlDbType.Int32, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") },
{ (int)MySqlDbType.Int64, ("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") },
{ (int)MySqlDbType.UByte, ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") },
{ (int)MySqlDbType.UInt16, ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt16") },
{ (int)MySqlDbType.UInt24, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") },
{ (int)MySqlDbType.UInt32, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") },
{ (int)MySqlDbType.UInt64, ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetInt64") },
{ (int)MySqlDbType.UByte, ("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") },
{ (int)MySqlDbType.UInt16, ("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt16") },
{ (int)MySqlDbType.UInt24, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") },
{ (int)MySqlDbType.UInt32, ("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt32") },
{ (int)MySqlDbType.UInt64, ("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetInt64") },
{ (int)MySqlDbType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") },
{ (int)MySqlDbType.Float, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") },
{ (int)MySqlDbType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") },
{ (int)MySqlDbType.Double, ("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") },
{ (int)MySqlDbType.Float, ("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") },
{ (int)MySqlDbType.Decimal, ("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") },
{ (int)MySqlDbType.Year, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") },
{ (int)MySqlDbType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") },
{ (int)MySqlDbType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") },
{ (int)MySqlDbType.Timestamp, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") },
{ (int)MySqlDbType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") },
{ (int)MySqlDbType.Year, ("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") },
{ (int)MySqlDbType.Time, ("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") },
{ (int)MySqlDbType.Date, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") },
{ (int)MySqlDbType.Timestamp, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") },
{ (int)MySqlDbType.DateTime, ("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") },
{ (int)MySqlDbType.TinyBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
{ (int)MySqlDbType.Blob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
{ (int)MySqlDbType.MediumBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
{ (int)MySqlDbType.LongBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
{ (int)MySqlDbType.TinyBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
{ (int)MySqlDbType.Blob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
{ (int)MySqlDbType.MediumBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
{ (int)MySqlDbType.LongBlob, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
{ (int)MySqlDbType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
{ (int)MySqlDbType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
{ (int)MySqlDbType.Binary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
{ (int)MySqlDbType.VarBinary, ("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
{ (int)MySqlDbType.TinyText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.MediumText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.LongText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.TinyText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.Text, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.MediumText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.LongText, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.Guid, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}", "GetString") },
{ (int)MySqlDbType.String, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.VarString, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.Guid, ("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}", "GetString") },
{ (int)MySqlDbType.String, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.VarString, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.VarChar, ("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
{ (int)MySqlDbType.Set, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Set", typeof(Enum), typeof(Enum), "{0}", "GetInt64") },
{ (int)MySqlDbType.Enum, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Enum", typeof(Enum), typeof(Enum), "{0}", "GetInt64") },
{ (int)MySqlDbType.Set, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Set", typeof(Enum), typeof(Enum), "{0}", "GetInt64") },
{ (int)MySqlDbType.Enum, ("(long?)", "long.Parse({0})", "{0}.ToInt64().ToString()", "Enum", typeof(Enum), typeof(Enum), "{0}", "GetInt64") },
{ (int)MySqlDbType.Geometry, ("(MygisGeometry)", "MygisGeometry.Parse({0}.Replace(StringifySplit, \"|\"))", "{0}.AsText().Replace(\"|\", StringifySplit)", "MygisGeometry", typeof(MygisGeometry), typeof(MygisGeometry), "{0}", "GetString") },
};
{ (int)MySqlDbType.Geometry, ("(MygisGeometry)", "MygisGeometry.Parse({0}.Replace(StringifySplit, \"|\"))", "{0}.AsText().Replace(\"|\", StringifySplit)", "MygisGeometry", typeof(MygisGeometry), typeof(MygisGeometry), "{0}", "GetString") },
};
public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null;
public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null;
public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null;
public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null;
public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null;
public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null;
public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null;
public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null;
public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null;
public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null;
public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null;
public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null;
public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null;
public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null;
public List<string> GetDatabases() {
var sql = @" select schema_name from information_schema.schemata where schema_name not in ('information_schema', 'mysql', 'performance_schema')";
var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList();
}
public List<string> GetDatabases()
{
var sql = @" select schema_name from information_schema.schemata where schema_name not in ('information_schema', 'mysql', 'performance_schema')";
var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList();
}
public List<DbTableInfo> GetTablesByDatabase(params string[] database2) {
var loc1 = new List<DbTableInfo>();
var loc2 = new Dictionary<string, DbTableInfo>();
var loc3 = new Dictionary<string, Dictionary<string, DbColumnInfo>>();
var database = database2?.ToArray();
public List<DbTableInfo> GetTablesByDatabase(params string[] database2)
{
var loc1 = new List<DbTableInfo>();
var loc2 = new Dictionary<string, DbTableInfo>();
var loc3 = new Dictionary<string, Dictionary<string, DbColumnInfo>>();
var database = database2?.ToArray();
if (database == null || database.Any() == false) {
using (var conn = _orm.Ado.MasterPool.Get()) {
if (string.IsNullOrEmpty(conn.Value.Database)) return loc1;
database = new[] { conn.Value.Database };
}
}
var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a)));
var sql = string.Format(@"
if (database == null || database.Any() == false)
{
using (var conn = _orm.Ado.MasterPool.Get())
{
if (string.IsNullOrEmpty(conn.Value.Database)) return loc1;
database = new[] { conn.Value.Database };
}
}
var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a)));
var sql = string.Format(@"
select
concat(a.table_schema, '.', a.table_name) 'id',
a.table_schema 'schema',
@ -158,38 +167,41 @@ a.table_comment,
a.table_type 'type'
from information_schema.tables a
where a.table_schema in ({0})", databaseIn);
var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
if (ds == null) return loc1;
var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
if (ds == null) return loc1;
var loc6 = new List<string>();
var loc66 = new List<string>();
foreach (var row in ds) {
var table_id = string.Concat(row[0]);
var schema = string.Concat(row[1]);
var table = string.Concat(row[2]);
var comment = string.Concat(row[3]);
var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE;
if (database.Length == 1) {
table_id = table_id.Substring(table_id.IndexOf('.') + 1);
schema = "";
}
loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type });
loc3.Add(table_id, new Dictionary<string, DbColumnInfo>());
switch (type) {
case DbTableType.TABLE:
case DbTableType.VIEW:
loc6.Add(table.Replace("'", "''"));
break;
case DbTableType.StoreProcedure:
loc66.Add(table.Replace("'", "''"));
break;
}
}
if (loc6.Count == 0) return loc1;
var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'";
var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'";
var loc6 = new List<string>();
var loc66 = new List<string>();
foreach (var row in ds)
{
var table_id = string.Concat(row[0]);
var schema = string.Concat(row[1]);
var table = string.Concat(row[2]);
var comment = string.Concat(row[3]);
var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE;
if (database.Length == 1)
{
table_id = table_id.Substring(table_id.IndexOf('.') + 1);
schema = "";
}
loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type });
loc3.Add(table_id, new Dictionary<string, DbColumnInfo>());
switch (type)
{
case DbTableType.TABLE:
case DbTableType.VIEW:
loc6.Add(table.Replace("'", "''"));
break;
case DbTableType.StoreProcedure:
loc66.Add(table.Replace("'", "''"));
break;
}
}
if (loc6.Count == 0) return loc1;
var loc8 = "'" + string.Join("','", loc6.ToArray()) + "'";
var loc88 = "'" + string.Join("','", loc66.ToArray()) + "'";
sql = string.Format(@"
sql = string.Format(@"
select
concat(a.table_schema, '.', a.table_name),
a.column_name,
@ -202,40 +214,43 @@ a.column_comment 'comment'
from information_schema.columns a
where a.table_schema in ({1}) and a.table_name in ({0})
", loc8, databaseIn);
ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
if (ds == null) return loc1;
ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
if (ds == null) return loc1;
foreach (var row in ds) {
string table_id = string.Concat(row[0]);
string column = string.Concat(row[1]);
string type = string.Concat(row[2]);
//long max_length = long.Parse(string.Concat(row[3]));
string sqlType = string.Concat(row[4]);
var m_len = Regex.Match(sqlType, @"\w+\((\d+)");
int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1;
bool is_nullable = string.Concat(row[5]) == "1";
bool is_identity = string.Concat(row[6]) == "1";
string comment = string.Concat(row[7]);
if (max_length == 0) max_length = -1;
if (database.Length == 1) {
table_id = table_id.Substring(table_id.IndexOf('.') + 1);
}
loc3[table_id].Add(column, new DbColumnInfo {
Name = column,
MaxLength = max_length,
IsIdentity = is_identity,
IsNullable = is_nullable,
IsPrimary = false,
DbTypeText = type,
DbTypeTextFull = sqlType,
Table = loc2[table_id],
Coment = comment
});
loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]);
loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]);
}
foreach (var row in ds)
{
string table_id = string.Concat(row[0]);
string column = string.Concat(row[1]);
string type = string.Concat(row[2]);
//long max_length = long.Parse(string.Concat(row[3]));
string sqlType = string.Concat(row[4]);
var m_len = Regex.Match(sqlType, @"\w+\((\d+)");
int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1;
bool is_nullable = string.Concat(row[5]) == "1";
bool is_identity = string.Concat(row[6]) == "1";
string comment = string.Concat(row[7]);
if (max_length == 0) max_length = -1;
if (database.Length == 1)
{
table_id = table_id.Substring(table_id.IndexOf('.') + 1);
}
loc3[table_id].Add(column, new DbColumnInfo
{
Name = column,
MaxLength = max_length,
IsIdentity = is_identity,
IsNullable = is_nullable,
IsPrimary = false,
DbTypeText = type,
DbTypeTextFull = sqlType,
Table = loc2[table_id],
Coment = comment
});
loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]);
loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]);
}
sql = string.Format(@"
sql = string.Format(@"
select
concat(a.constraint_schema, '.', a.table_name) 'table_id',
a.column_name,
@ -247,53 +262,59 @@ case when a.constraint_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey',
from information_schema.key_column_usage a
where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position_in_unique_constraint)
", loc8, databaseIn);
ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
if (ds == null) return loc1;
ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
if (ds == null) return loc1;
var indexColumns = new Dictionary<string, Dictionary<string, List<DbColumnInfo>>>();
var uniqueColumns = new Dictionary<string, Dictionary<string, List<DbColumnInfo>>>();
foreach (var row in ds) {
string table_id = string.Concat(row[0]);
string column = string.Concat(row[1]);
string index_id = string.Concat(row[2]);
bool is_unique = string.Concat(row[3]) == "1";
bool is_primary_key = string.Concat(row[4]) == "1";
bool is_clustered = string.Concat(row[5]) == "1";
int is_desc = int.Parse(string.Concat(row[6]));
if (database.Length == 1) {
table_id = table_id.Substring(table_id.IndexOf('.') + 1);
}
if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue;
var loc9 = loc3[table_id][column];
if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key;
var indexColumns = new Dictionary<string, Dictionary<string, List<DbColumnInfo>>>();
var uniqueColumns = new Dictionary<string, Dictionary<string, List<DbColumnInfo>>>();
foreach (var row in ds)
{
string table_id = string.Concat(row[0]);
string column = string.Concat(row[1]);
string index_id = string.Concat(row[2]);
bool is_unique = string.Concat(row[3]) == "1";
bool is_primary_key = string.Concat(row[4]) == "1";
bool is_clustered = string.Concat(row[5]) == "1";
int is_desc = int.Parse(string.Concat(row[6]));
if (database.Length == 1)
{
table_id = table_id.Substring(table_id.IndexOf('.') + 1);
}
if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue;
var loc9 = loc3[table_id][column];
if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key;
Dictionary<string, List<DbColumnInfo>> loc10 = null;
List<DbColumnInfo> loc11 = null;
if (!indexColumns.TryGetValue(table_id, out loc10))
indexColumns.Add(table_id, loc10 = new Dictionary<string, List<DbColumnInfo>>());
if (!loc10.TryGetValue(index_id, out loc11))
loc10.Add(index_id, loc11 = new List<DbColumnInfo>());
loc11.Add(loc9);
if (is_unique && !is_primary_key) {
if (!uniqueColumns.TryGetValue(table_id, out loc10))
uniqueColumns.Add(table_id, loc10 = new Dictionary<string, List<DbColumnInfo>>());
if (!loc10.TryGetValue(index_id, out loc11))
loc10.Add(index_id, loc11 = new List<DbColumnInfo>());
loc11.Add(loc9);
}
}
foreach (string table_id in indexColumns.Keys) {
foreach (var column in indexColumns[table_id])
loc2[table_id].IndexesDict.Add(column.Key, column.Value);
}
foreach (string table_id in uniqueColumns.Keys) {
foreach (var column in uniqueColumns[table_id]) {
column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
loc2[table_id].UniquesDict.Add(column.Key, column.Value);
}
}
Dictionary<string, List<DbColumnInfo>> loc10 = null;
List<DbColumnInfo> loc11 = null;
if (!indexColumns.TryGetValue(table_id, out loc10))
indexColumns.Add(table_id, loc10 = new Dictionary<string, List<DbColumnInfo>>());
if (!loc10.TryGetValue(index_id, out loc11))
loc10.Add(index_id, loc11 = new List<DbColumnInfo>());
loc11.Add(loc9);
if (is_unique && !is_primary_key)
{
if (!uniqueColumns.TryGetValue(table_id, out loc10))
uniqueColumns.Add(table_id, loc10 = new Dictionary<string, List<DbColumnInfo>>());
if (!loc10.TryGetValue(index_id, out loc11))
loc10.Add(index_id, loc11 = new List<DbColumnInfo>());
loc11.Add(loc9);
}
}
foreach (string table_id in indexColumns.Keys)
{
foreach (var column in indexColumns[table_id])
loc2[table_id].IndexesDict.Add(column.Key, column.Value);
}
foreach (string table_id in uniqueColumns.Keys)
{
foreach (var column in uniqueColumns[table_id])
{
column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
loc2[table_id].UniquesDict.Add(column.Key, column.Value);
}
}
sql = string.Format(@"
sql = string.Format(@"
select
concat(a.constraint_schema, '.', a.table_name) 'table_id',
a.column_name,
@ -304,80 +325,91 @@ a.referenced_column_name 'ref_column'
from information_schema.key_column_usage a
where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(position_in_unique_constraint)
", loc8, databaseIn);
ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
if (ds == null) return loc1;
ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
if (ds == null) return loc1;
var fkColumns = new Dictionary<string, Dictionary<string, DbForeignInfo>>();
foreach (var row in ds) {
string table_id = string.Concat(row[0]);
string column = string.Concat(row[1]);
string fk_id = string.Concat(row[2]);
string ref_table_id = string.Concat(row[3]);
bool is_foreign_key = string.Concat(row[4]) == "1";
string referenced_column = string.Concat(row[5]);
if (database.Length == 1) {
table_id = table_id.Substring(table_id.IndexOf('.') + 1);
ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1);
}
if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue;
var loc9 = loc3[table_id][column];
if (loc2.ContainsKey(ref_table_id) == false) continue;
var loc10 = loc2[ref_table_id];
var loc11 = loc3[ref_table_id][referenced_column];
var fkColumns = new Dictionary<string, Dictionary<string, DbForeignInfo>>();
foreach (var row in ds)
{
string table_id = string.Concat(row[0]);
string column = string.Concat(row[1]);
string fk_id = string.Concat(row[2]);
string ref_table_id = string.Concat(row[3]);
bool is_foreign_key = string.Concat(row[4]) == "1";
string referenced_column = string.Concat(row[5]);
if (database.Length == 1)
{
table_id = table_id.Substring(table_id.IndexOf('.') + 1);
ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1);
}
if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue;
var loc9 = loc3[table_id][column];
if (loc2.ContainsKey(ref_table_id) == false) continue;
var loc10 = loc2[ref_table_id];
var loc11 = loc3[ref_table_id][referenced_column];
Dictionary<string, DbForeignInfo> loc12 = null;
DbForeignInfo loc13 = null;
if (!fkColumns.TryGetValue(table_id, out loc12))
fkColumns.Add(table_id, loc12 = new Dictionary<string, DbForeignInfo>());
if (!loc12.TryGetValue(fk_id, out loc13))
loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 });
loc13.Columns.Add(loc9);
loc13.ReferencedColumns.Add(loc11);
}
foreach (var table_id in fkColumns.Keys)
foreach (var fk in fkColumns[table_id])
loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value);
Dictionary<string, DbForeignInfo> loc12 = null;
DbForeignInfo loc13 = null;
if (!fkColumns.TryGetValue(table_id, out loc12))
fkColumns.Add(table_id, loc12 = new Dictionary<string, DbForeignInfo>());
if (!loc12.TryGetValue(fk_id, out loc13))
loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 });
loc13.Columns.Add(loc9);
loc13.ReferencedColumns.Add(loc11);
}
foreach (var table_id in fkColumns.Keys)
foreach (var fk in fkColumns[table_id])
loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value);
foreach (var table_id in loc3.Keys) {
foreach (var loc5 in loc3[table_id].Values) {
loc2[table_id].Columns.Add(loc5);
if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5);
if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5);
}
}
foreach (var loc4 in loc2.Values) {
if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) {
foreach (var loc5 in loc4.UniquesDict.First().Value) {
loc5.IsPrimary = true;
loc4.Primarys.Add(loc5);
}
}
loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
loc4.Columns.Sort((c1, c2) => {
int compare = c2.IsPrimary.CompareTo(c1.IsPrimary);
if (compare == 0) {
bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any();
bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any();
compare = b2.CompareTo(b1);
}
if (compare == 0) compare = c1.Name.CompareTo(c2.Name);
return compare;
});
loc1.Add(loc4);
}
loc1.Sort((t1, t2) => {
var ret = t1.Schema.CompareTo(t2.Schema);
if (ret == 0) ret = t1.Name.CompareTo(t2.Name);
return ret;
});
foreach (var table_id in loc3.Keys)
{
foreach (var loc5 in loc3[table_id].Values)
{
loc2[table_id].Columns.Add(loc5);
if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5);
if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5);
}
}
foreach (var loc4 in loc2.Values)
{
if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0)
{
foreach (var loc5 in loc4.UniquesDict.First().Value)
{
loc5.IsPrimary = true;
loc4.Primarys.Add(loc5);
}
}
loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
loc4.Columns.Sort((c1, c2) =>
{
int compare = c2.IsPrimary.CompareTo(c1.IsPrimary);
if (compare == 0)
{
bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any();
bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any();
compare = b2.CompareTo(b1);
}
if (compare == 0) compare = c1.Name.CompareTo(c2.Name);
return compare;
});
loc1.Add(loc4);
}
loc1.Sort((t1, t2) =>
{
var ret = t1.Schema.CompareTo(t2.Schema);
if (ret == 0) ret = t1.Name.CompareTo(t2.Name);
return ret;
});
loc2.Clear();
loc3.Clear();
return loc1;
}
loc2.Clear();
loc3.Clear();
return loc1;
}
public List<DbEnumInfo> GetEnumsByDatabase(params string[] database) {
return new List<DbEnumInfo>();
}
}
public List<DbEnumInfo> GetEnumsByDatabase(params string[] database)
{
return new List<DbEnumInfo>();
}
}
}

View File

@ -7,392 +7,447 @@ using System.Linq;
using System.Linq.Expressions;
using System.Text;
namespace FreeSql.MySql {
class MySqlExpression : CommonExpression {
namespace FreeSql.MySql
{
class MySqlExpression : CommonExpression
{
public MySqlExpression(CommonUtils common) : base(common) { }
public MySqlExpression(CommonUtils common) : base(common) { }
public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.NodeType) {
case ExpressionType.Convert:
var operandExp = (exp as UnaryExpression)?.Operand;
var gentype = exp.Type.NullableTypeOrThis();
if (gentype != operandExp.Type.NullableTypeOrThis()) {
switch (gentype.ToString()) {
case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))";
case "System.Byte": return $"cast({getExp(operandExp)} as unsigned)";
case "System.Char": return $"substr(cast({getExp(operandExp)} as char), 1, 1)";
case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)";
case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))";
case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))";
case "System.Int16":
case "System.Int32":
case "System.Int64":
case "System.SByte": return $"cast({getExp(operandExp)} as signed)";
case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))";
case "System.String": return $"cast({getExp(operandExp)} as char)";
case "System.UInt16":
case "System.UInt32":
case "System.UInt64": return $"cast({getExp(operandExp)} as unsigned)";
case "System.Guid": return $"substr(cast({getExp(operandExp)} as char), 1, 36)";
}
}
break;
case ExpressionType.Call:
var callExp = exp as MethodCallExpression;
public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc)
{
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.NodeType)
{
case ExpressionType.Convert:
var operandExp = (exp as UnaryExpression)?.Operand;
var gentype = exp.Type.NullableTypeOrThis();
if (gentype != operandExp.Type.NullableTypeOrThis())
{
switch (gentype.ToString())
{
case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))";
case "System.Byte": return $"cast({getExp(operandExp)} as unsigned)";
case "System.Char": return $"substr(cast({getExp(operandExp)} as char), 1, 1)";
case "System.DateTime": return $"cast({getExp(operandExp)} as datetime)";
case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))";
case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))";
case "System.Int16":
case "System.Int32":
case "System.Int64":
case "System.SByte": return $"cast({getExp(operandExp)} as signed)";
case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))";
case "System.String": return $"cast({getExp(operandExp)} as char)";
case "System.UInt16":
case "System.UInt32":
case "System.UInt64": return $"cast({getExp(operandExp)} as unsigned)";
case "System.Guid": return $"substr(cast({getExp(operandExp)} as char), 1, 36)";
}
}
break;
case ExpressionType.Call:
var callExp = exp as MethodCallExpression;
switch (callExp.Method.Name) {
case "Parse":
case "TryParse":
switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) {
case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))";
case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as unsigned)";
case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 1)";
case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)";
case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))";
case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))";
case "System.Int16":
case "System.Int32":
case "System.Int64":
case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as signed)";
case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))";
case "System.UInt16":
case "System.UInt32":
case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as unsigned)";
case "System.Guid": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 36)";
}
break;
case "NewGuid":
break;
case "Next":
if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as signed)";
break;
case "NextDouble":
if (callExp.Object?.Type == typeof(Random)) return "rand()";
break;
case "Random":
if (callExp.Method.DeclaringType.IsNumberType()) return "rand()";
break;
case "ToString":
if (callExp.Object != null) return $"cast({getExp(callExp.Object)} as char)";
break;
}
switch (callExp.Method.Name)
{
case "Parse":
case "TryParse":
switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString())
{
case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))";
case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as unsigned)";
case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 1)";
case "System.DateTime": return $"cast({getExp(callExp.Arguments[0])} as datetime)";
case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))";
case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))";
case "System.Int16":
case "System.Int32":
case "System.Int64":
case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as signed)";
case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))";
case "System.UInt16":
case "System.UInt32":
case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as unsigned)";
case "System.Guid": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 36)";
}
break;
case "NewGuid":
break;
case "Next":
if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as signed)";
break;
case "NextDouble":
if (callExp.Object?.Type == typeof(Random)) return "rand()";
break;
case "Random":
if (callExp.Method.DeclaringType.IsNumberType()) return "rand()";
break;
case "ToString":
if (callExp.Object != null) return $"cast({getExp(callExp.Object)} as char)";
break;
}
var objExp = callExp.Object;
var objType = objExp?.Type;
if (objType?.FullName == "System.Byte[]") return null;
var objExp = callExp.Object;
var objType = objExp?.Type;
if (objType?.FullName == "System.Byte[]") return null;
var argIndex = 0;
if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) {
objExp = callExp.Arguments.FirstOrDefault();
objType = objExp?.Type;
argIndex++;
}
if (objType == null) objType = callExp.Method.DeclaringType;
if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType)) {
var left = objExp == null ? null : getExp(objExp);
switch (callExp.Method.Name) {
case "Contains":
//判断 in
return $"({getExp(callExp.Arguments[argIndex])}) in {left}";
}
}
break;
case ExpressionType.NewArrayInit:
var arrExp = exp as NewArrayExpression;
var arrSb = new StringBuilder();
arrSb.Append("(");
for (var a = 0; a < arrExp.Expressions.Count; a++) {
if (a > 0) arrSb.Append(",");
arrSb.Append(getExp(arrExp.Expressions[a]));
}
if (arrSb.Length == 1) arrSb.Append("NULL");
return arrSb.Append(")").ToString();
case ExpressionType.ListInit:
var listExp = exp as ListInitExpression;
var listSb = new StringBuilder();
listSb.Append("(");
for (var a = 0; a < listExp.Initializers.Count; a++) {
if (listExp.Initializers[a].Arguments.Any() == false) continue;
if (a > 0) listSb.Append(",");
listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault()));
}
if (listSb.Length == 1) listSb.Append("NULL");
return listSb.Append(")").ToString();
case ExpressionType.New:
var newExp = exp as NewExpression;
if (typeof(IList).IsAssignableFrom(newExp.Type)) {
if (newExp.Arguments.Count == 0) return "(NULL)";
if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)";
return getExp(newExp.Arguments[0]);
}
return null;
}
return null;
}
var argIndex = 0;
if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable))
{
objExp = callExp.Arguments.FirstOrDefault();
objType = objExp?.Type;
argIndex++;
}
if (objType == null) objType = callExp.Method.DeclaringType;
if (objType != null || objType.IsArray || typeof(IList).IsAssignableFrom(callExp.Method.DeclaringType))
{
var left = objExp == null ? null : getExp(objExp);
switch (callExp.Method.Name)
{
case "Contains":
//判断 in
return $"({getExp(callExp.Arguments[argIndex])}) in {left}";
}
}
break;
case ExpressionType.NewArrayInit:
var arrExp = exp as NewArrayExpression;
var arrSb = new StringBuilder();
arrSb.Append("(");
for (var a = 0; a < arrExp.Expressions.Count; a++)
{
if (a > 0) arrSb.Append(",");
arrSb.Append(getExp(arrExp.Expressions[a]));
}
if (arrSb.Length == 1) arrSb.Append("NULL");
return arrSb.Append(")").ToString();
case ExpressionType.ListInit:
var listExp = exp as ListInitExpression;
var listSb = new StringBuilder();
listSb.Append("(");
for (var a = 0; a < listExp.Initializers.Count; a++)
{
if (listExp.Initializers[a].Arguments.Any() == false) continue;
if (a > 0) listSb.Append(",");
listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault()));
}
if (listSb.Length == 1) listSb.Append("NULL");
return listSb.Append(")").ToString();
case ExpressionType.New:
var newExp = exp as NewExpression;
if (typeof(IList).IsAssignableFrom(newExp.Type))
{
if (newExp.Arguments.Count == 0) return "(NULL)";
if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)";
return getExp(newExp.Arguments[0]);
}
return null;
}
return null;
}
public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Empty": return "''";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Length": return $"char_length({left})";
}
return null;
}
public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Now": return "now()";
case "UtcNow": return "utc_timestamp()";
case "Today": return "curdate()";
case "MinValue": return "cast('0001/1/1 0:00:00' as datetime)";
case "MaxValue": return "cast('9999/12/31 23:59:59' as datetime)";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Date": return $"cast(date_format({left},'%Y-%m-%d') as datetime)";
case "TimeOfDay": return $"timestampdiff(microsecond, date_format({left},'%Y-%m-%d'), {left})";
case "DayOfWeek": return $"(dayofweek({left})-1)";
case "Day": return $"dayofmonth({left})";
case "DayOfYear": return $"dayofyear({left})";
case "Month": return $"month({left})";
case "Year": return $"year({left})";
case "Hour": return $"hour({left})";
case "Minute": return $"minute({left})";
case "Second": return $"second({left})";
case "Millisecond": return $"floor(microsecond({left})/1000)";
case "Ticks": return $"(timestampdiff(microsecond, '0001-1-1', {left})*10)";
}
return null;
}
public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Zero": return "0";
case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10
case "MaxValue": return "922337203685477580";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Days": return $"(({left}) div {(long)1000000 * 60 * 60 * 24})";
case "Hours": return $"(({left}) div {(long)1000000 * 60 * 60} mod 24)";
case "Milliseconds": return $"(({left}) div 1000 mod 1000)";
case "Minutes": return $"(({left}) div {(long)1000000 * 60} mod 60)";
case "Seconds": return $"(({left}) div 1000000 mod 60)";
case "Ticks": return $"(({left}) * 10)";
case "TotalDays": return $"(({left}) / {(long)1000000 * 60 * 60 * 24})";
case "TotalHours": return $"(({left}) / {(long)1000000 * 60 * 60})";
case "TotalMilliseconds": return $"(({left}) / 1000)";
case "TotalMinutes": return $"(({left}) / {(long)1000000 * 60})";
case "TotalSeconds": return $"(({left}) / 1000000)";
}
return null;
}
public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc)
{
if (exp.Expression == null)
{
switch (exp.Member.Name)
{
case "Empty": return "''";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name)
{
case "Length": return $"char_length({left})";
}
return null;
}
public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc)
{
if (exp.Expression == null)
{
switch (exp.Member.Name)
{
case "Now": return "now()";
case "UtcNow": return "utc_timestamp()";
case "Today": return "curdate()";
case "MinValue": return "cast('0001/1/1 0:00:00' as datetime)";
case "MaxValue": return "cast('9999/12/31 23:59:59' as datetime)";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name)
{
case "Date": return $"cast(date_format({left},'%Y-%m-%d') as datetime)";
case "TimeOfDay": return $"timestampdiff(microsecond, date_format({left},'%Y-%m-%d'), {left})";
case "DayOfWeek": return $"(dayofweek({left})-1)";
case "Day": return $"dayofmonth({left})";
case "DayOfYear": return $"dayofyear({left})";
case "Month": return $"month({left})";
case "Year": return $"year({left})";
case "Hour": return $"hour({left})";
case "Minute": return $"minute({left})";
case "Second": return $"second({left})";
case "Millisecond": return $"floor(microsecond({left})/1000)";
case "Ticks": return $"(timestampdiff(microsecond, '0001-1-1', {left})*10)";
}
return null;
}
public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc)
{
if (exp.Expression == null)
{
switch (exp.Member.Name)
{
case "Zero": return "0";
case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10
case "MaxValue": return "922337203685477580";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name)
{
case "Days": return $"(({left}) div {(long)1000000 * 60 * 60 * 24})";
case "Hours": return $"(({left}) div {(long)1000000 * 60 * 60} mod 24)";
case "Milliseconds": return $"(({left}) div 1000 mod 1000)";
case "Minutes": return $"(({left}) div {(long)1000000 * 60} mod 60)";
case "Seconds": return $"(({left}) div 1000000 mod 60)";
case "Ticks": return $"(({left}) * 10)";
case "TotalDays": return $"(({left}) / {(long)1000000 * 60 * 60 * 24})";
case "TotalHours": return $"(({left}) / {(long)1000000 * 60 * 60})";
case "TotalMilliseconds": return $"(({left}) / 1000)";
case "TotalMinutes": return $"(({left}) / {(long)1000000 * 60})";
case "TotalSeconds": return $"(({left}) / 1000000)";
}
return null;
}
public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "IsNullOrEmpty":
var arg1 = getExp(exp.Arguments[0]);
return $"({arg1} is null or {arg1} = '')";
case "Concat":
return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null);
}
} else {
var left = getExp(exp.Object);
switch (exp.Method.Name) {
case "StartsWith":
case "EndsWith":
case "Contains":
var args0Value = getExp(exp.Arguments[0]);
if (args0Value == "NULL") return $"({left}) IS NULL";
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"concat({args0Value}, '%')")}";
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"concat('%', {args0Value})")}";
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
return $"({left}) LIKE concat('%', {args0Value}, '%')";
case "ToLower": return $"lower({left})";
case "ToUpper": return $"upper({left})";
case "Substring":
var substrArgs1 = getExp(exp.Arguments[0]);
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
else substrArgs1 += "+1";
if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})";
return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})";
case "IndexOf":
var indexOfFindStr = getExp(exp.Arguments[0]);
if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") {
var locateArgs1 = getExp(exp.Arguments[1]);
if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString();
else locateArgs1 += "+1";
return $"(locate({left}, {indexOfFindStr}, {locateArgs1})-1)";
}
return $"(locate({left}, {indexOfFindStr})-1)";
case "PadLeft":
if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})";
return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
case "PadRight":
if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})";
return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
case "Trim":
case "TrimStart":
case "TrimEnd":
if (exp.Arguments.Count == 0) {
if (exp.Method.Name == "Trim") return $"trim({left})";
if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
}
foreach (var argsTrim02 in exp.Arguments) {
var argsTrim01s = new[] { argsTrim02 };
if (argsTrim02.NodeType == ExpressionType.NewArrayInit) {
var arritem = argsTrim02 as NewArrayExpression;
argsTrim01s = arritem.Expressions.ToArray();
}
foreach (var argsTrim01 in argsTrim01s) {
if (exp.Method.Name == "Trim") left = $"trim({getExp(argsTrim01)} from {left})";
if (exp.Method.Name == "TrimStart") left = $"trim(leading {getExp(argsTrim01)} from {left})";
if (exp.Method.Name == "TrimEnd") left = $"trim(trailing {getExp(argsTrim01)} from {left})";
}
}
return left;
case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
case "CompareTo": return $"strcmp({left}, {getExp(exp.Arguments[0])})";
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
}
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.Method.Name) {
case "Abs": return $"abs({getExp(exp.Arguments[0])})";
case "Sign": return $"sign({getExp(exp.Arguments[0])})";
case "Floor": return $"floor({getExp(exp.Arguments[0])})";
case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})";
case "Round":
if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
return $"round({getExp(exp.Arguments[0])})";
case "Exp": return $"exp({getExp(exp.Arguments[0])})";
case "Log": return $"log({getExp(exp.Arguments[0])})";
case "Log10": return $"log10({getExp(exp.Arguments[0])})";
case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})";
case "Cos": return $"cos({getExp(exp.Arguments[0])})";
case "Sin": return $"sin({getExp(exp.Arguments[0])})";
case "Tan": return $"tan({getExp(exp.Arguments[0])})";
case "Acos": return $"acos({getExp(exp.Arguments[0])})";
case "Asin": return $"asin({getExp(exp.Arguments[0])})";
case "Atan": return $"atan({getExp(exp.Arguments[0])})";
case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
case "Truncate": return $"truncate({getExp(exp.Arguments[0])}, 0)";
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))";
case "DaysInMonth": return $"dayofmonth(last_day(concat({getExp(exp.Arguments[0])}, '-', {getExp(exp.Arguments[1])}, '-01')))";
case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})";
public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc)
{
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null)
{
switch (exp.Method.Name)
{
case "IsNullOrEmpty":
var arg1 = getExp(exp.Arguments[0]);
return $"({arg1} is null or {arg1} = '')";
case "Concat":
return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null);
}
}
else
{
var left = getExp(exp.Object);
switch (exp.Method.Name)
{
case "StartsWith":
case "EndsWith":
case "Contains":
var args0Value = getExp(exp.Arguments[0]);
if (args0Value == "NULL") return $"({left}) IS NULL";
if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"concat({args0Value}, '%')")}";
if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"concat('%', {args0Value})")}";
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
return $"({left}) LIKE concat('%', {args0Value}, '%')";
case "ToLower": return $"lower({left})";
case "ToUpper": return $"upper({left})";
case "Substring":
var substrArgs1 = getExp(exp.Arguments[0]);
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
else substrArgs1 += "+1";
if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})";
return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})";
case "IndexOf":
var indexOfFindStr = getExp(exp.Arguments[0]);
if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32")
{
var locateArgs1 = getExp(exp.Arguments[1]);
if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString();
else locateArgs1 += "+1";
return $"(locate({left}, {indexOfFindStr}, {locateArgs1})-1)";
}
return $"(locate({left}, {indexOfFindStr})-1)";
case "PadLeft":
if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})";
return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
case "PadRight":
if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})";
return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
case "Trim":
case "TrimStart":
case "TrimEnd":
if (exp.Arguments.Count == 0)
{
if (exp.Method.Name == "Trim") return $"trim({left})";
if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
}
foreach (var argsTrim02 in exp.Arguments)
{
var argsTrim01s = new[] { argsTrim02 };
if (argsTrim02.NodeType == ExpressionType.NewArrayInit)
{
var arritem = argsTrim02 as NewArrayExpression;
argsTrim01s = arritem.Expressions.ToArray();
}
foreach (var argsTrim01 in argsTrim01s)
{
if (exp.Method.Name == "Trim") left = $"trim({getExp(argsTrim01)} from {left})";
if (exp.Method.Name == "TrimStart") left = $"trim(leading {getExp(argsTrim01)} from {left})";
if (exp.Method.Name == "TrimEnd") left = $"trim(trailing {getExp(argsTrim01)} from {left})";
}
}
return left;
case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
case "CompareTo": return $"strcmp({left}, {getExp(exp.Arguments[0])})";
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
}
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc)
{
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.Method.Name)
{
case "Abs": return $"abs({getExp(exp.Arguments[0])})";
case "Sign": return $"sign({getExp(exp.Arguments[0])})";
case "Floor": return $"floor({getExp(exp.Arguments[0])})";
case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})";
case "Round":
if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
return $"round({getExp(exp.Arguments[0])})";
case "Exp": return $"exp({getExp(exp.Arguments[0])})";
case "Log": return $"log({getExp(exp.Arguments[0])})";
case "Log10": return $"log10({getExp(exp.Arguments[0])})";
case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})";
case "Cos": return $"cos({getExp(exp.Arguments[0])})";
case "Sin": return $"sin({getExp(exp.Arguments[0])})";
case "Tan": return $"tan({getExp(exp.Arguments[0])})";
case "Acos": return $"acos({getExp(exp.Arguments[0])})";
case "Asin": return $"asin({getExp(exp.Arguments[0])})";
case "Atan": return $"atan({getExp(exp.Arguments[0])})";
case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
case "Truncate": return $"truncate({getExp(exp.Arguments[0])}, 0)";
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc)
{
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null)
{
switch (exp.Method.Name)
{
case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))";
case "DaysInMonth": return $"dayofmonth(last_day(concat({getExp(exp.Arguments[0])}, '-', {getExp(exp.Arguments[1])}, '-01')))";
case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})";
case "IsLeapYear":
var isLeapYearArgs1 = getExp(exp.Arguments[0]);
return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)";
case "IsLeapYear":
var isLeapYearArgs1 = getExp(exp.Arguments[0]);
return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)";
case "Parse": return $"cast({getExp(exp.Arguments[0])} as datetime)";
case "ParseExact":
case "TryParse":
case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as datetime)";
}
} else {
var left = getExp(exp.Object);
var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]);
switch (exp.Method.Name) {
case "Add": return $"date_add({left}, interval ({args1}) microsecond)";
case "AddDays": return $"date_add({left}, interval ({args1}) day)";
case "AddHours": return $"date_add({left}, interval ({args1}) hour)";
case "AddMilliseconds": return $"date_add({left}, interval ({args1})*1000 microsecond)";
case "AddMinutes": return $"date_add({left}, interval ({args1}) minute)";
case "AddMonths": return $"date_add({left}, interval ({args1}) month)";
case "AddSeconds": return $"date_add({left}, interval ({args1}) second)";
case "AddTicks": return $"date_add({left}, interval ({args1})/10 microsecond)";
case "AddYears": return $"date_add({left}, interval ({args1}) year)";
case "Subtract":
switch((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName) {
case "System.DateTime": return $"timestampdiff(microsecond, {args1}, {left})";
case "System.TimeSpan": return $"date_sub({left}, interval ({args1}) microsecond)";
}
break;
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})";
case "ToString": return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')";
}
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))";
case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})";
case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})";
case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})";
case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)";
case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})";
case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)";
case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)";
case "Parse": return $"cast({getExp(exp.Arguments[0])} as signed)";
case "ParseExact":
case "TryParse":
case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as signed)";
}
} else {
var left = getExp(exp.Object);
var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]);
switch (exp.Method.Name) {
case "Add": return $"({left}+{args1})";
case "Subtract": return $"({left}-({args1}))";
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))";
case "ToString": return $"cast({left} as char)";
}
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))";
case "ToByte": return $"cast({getExp(exp.Arguments[0])} as unsigned)";
case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as char), 1, 1)";
case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as datetime)";
case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))";
case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))";
case "ToInt16":
case "ToInt32":
case "ToInt64":
case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as signed)";
case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))";
case "ToString": return $"cast({getExp(exp.Arguments[0])} as char)";
case "ToUInt16":
case "ToUInt32":
case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as unsigned)";
}
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
}
case "Parse": return $"cast({getExp(exp.Arguments[0])} as datetime)";
case "ParseExact":
case "TryParse":
case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as datetime)";
}
}
else
{
var left = getExp(exp.Object);
var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]);
switch (exp.Method.Name)
{
case "Add": return $"date_add({left}, interval ({args1}) microsecond)";
case "AddDays": return $"date_add({left}, interval ({args1}) day)";
case "AddHours": return $"date_add({left}, interval ({args1}) hour)";
case "AddMilliseconds": return $"date_add({left}, interval ({args1})*1000 microsecond)";
case "AddMinutes": return $"date_add({left}, interval ({args1}) minute)";
case "AddMonths": return $"date_add({left}, interval ({args1}) month)";
case "AddSeconds": return $"date_add({left}, interval ({args1}) second)";
case "AddTicks": return $"date_add({left}, interval ({args1})/10 microsecond)";
case "AddYears": return $"date_add({left}, interval ({args1}) year)";
case "Subtract":
switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault() : exp.Arguments[0].Type).FullName)
{
case "System.DateTime": return $"timestampdiff(microsecond, {args1}, {left})";
case "System.TimeSpan": return $"date_sub({left}, interval ({args1}) microsecond)";
}
break;
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})";
case "ToString": return $"date_format({left}, '%Y-%m-%d %H:%i:%s.%f')";
}
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc)
{
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null)
{
switch (exp.Method.Name)
{
case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))";
case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})";
case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})";
case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})";
case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)";
case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})";
case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)";
case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)";
case "Parse": return $"cast({getExp(exp.Arguments[0])} as signed)";
case "ParseExact":
case "TryParse":
case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as signed)";
}
}
else
{
var left = getExp(exp.Object);
var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]);
switch (exp.Method.Name)
{
case "Add": return $"({left}+{args1})";
case "Subtract": return $"({left}-({args1}))";
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
case "CompareTo": return $"({left}-({getExp(exp.Arguments[0])}))";
case "ToString": return $"cast({left} as char)";
}
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc)
{
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null)
{
switch (exp.Method.Name)
{
case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))";
case "ToByte": return $"cast({getExp(exp.Arguments[0])} as unsigned)";
case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as char), 1, 1)";
case "ToDateTime": return $"cast({getExp(exp.Arguments[0])} as datetime)";
case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))";
case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))";
case "ToInt16":
case "ToInt32":
case "ToInt64":
case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as signed)";
case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))";
case "ToString": return $"cast({getExp(exp.Arguments[0])} as char)";
case "ToUInt16":
case "ToUInt32":
case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as unsigned)";
}
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
}
}

View File

@ -1,11 +1,12 @@
public static partial class FreeSqlGlobalExtensions {
public static partial class FreeSqlGlobalExtensions
{
/// <summary>
/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
/// </summary>
/// <param name="that"></param>
/// <param name="args"></param>
/// <returns></returns>
public static string FormatMySql(this string that, params object[] args) => _mysqlAdo.Addslashes(that, args);
static FreeSql.MySql.MySqlAdo _mysqlAdo = new FreeSql.MySql.MySqlAdo();
/// <summary>
/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
/// </summary>
/// <param name="that"></param>
/// <param name="args"></param>
/// <returns></returns>
public static string FormatMySql(this string that, params object[] args) => _mysqlAdo.Addslashes(that, args);
static FreeSql.MySql.MySqlAdo _mysqlAdo = new FreeSql.MySql.MySqlAdo();
}

View File

@ -6,72 +6,80 @@ using System.Collections.Generic;
using System.Data.Common;
using System.Linq.Expressions;
namespace FreeSql.MySql {
namespace FreeSql.MySql
{
public class MySqlProvider<TMark> : IFreeSql<TMark> {
public class MySqlProvider<TMark> : IFreeSql<TMark>
{
static MySqlProvider() {
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPoint)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisLineString)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPolygon)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPoint)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiLineString)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPolygon)] = true;
static MySqlProvider()
{
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPoint)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisLineString)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPolygon)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPoint)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiLineString)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPolygon)] = true;
var MethodMygisGeometryParse = typeof(MygisGeometry).GetMethod("Parse", new[] { typeof(string) });
Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, string typeFullName) => {
switch (typeFullName) {
case "MygisPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPoint)));
case "MygisLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisLineString)));
case "MygisPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPolygon)));
case "MygisMultiPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPoint)));
case "MygisMultiLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiLineString)));
case "MygisMultiPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPolygon)));
}
return null;
});
}
var MethodMygisGeometryParse = typeof(MygisGeometry).GetMethod("Parse", new[] { typeof(string) });
Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, string typeFullName) =>
{
switch (typeFullName)
{
case "MygisPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPoint)));
case "MygisLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisLineString)));
case "MygisPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPolygon)));
case "MygisMultiPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPoint)));
case "MygisMultiLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiLineString)));
case "MygisMultiPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPolygon)));
}
return null;
});
}
public ISelect<T1> Select<T1>() where T1 : class => new MySqlSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, null);
public ISelect<T1> Select<T1>(object dywhere) where T1 : class => new MySqlSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
public IInsert<T1> Insert<T1>() where T1 : class => new MySqlInsert<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression);
public IInsert<T1> Insert<T1>(T1 source) where T1 : class => this.Insert<T1>().AppendData(source);
public IInsert<T1> Insert<T1>(T1[] source) where T1 : class => this.Insert<T1>().AppendData(source);
public IInsert<T1> Insert<T1>(IEnumerable<T1> source) where T1 : class => this.Insert<T1>().AppendData(source);
public IUpdate<T1> Update<T1>() where T1 : class => new MySqlUpdate<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, null);
public IUpdate<T1> Update<T1>(object dywhere) where T1 : class => new MySqlUpdate<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
public IDelete<T1> Delete<T1>() where T1 : class => new MySqlDelete<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, null);
public IDelete<T1> Delete<T1>(object dywhere) where T1 : class => new MySqlDelete<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
public ISelect<T1> Select<T1>() where T1 : class => new MySqlSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, null);
public ISelect<T1> Select<T1>(object dywhere) where T1 : class => new MySqlSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
public IInsert<T1> Insert<T1>() where T1 : class => new MySqlInsert<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression);
public IInsert<T1> Insert<T1>(T1 source) where T1 : class => this.Insert<T1>().AppendData(source);
public IInsert<T1> Insert<T1>(T1[] source) where T1 : class => this.Insert<T1>().AppendData(source);
public IInsert<T1> Insert<T1>(IEnumerable<T1> source) where T1 : class => this.Insert<T1>().AppendData(source);
public IUpdate<T1> Update<T1>() where T1 : class => new MySqlUpdate<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, null);
public IUpdate<T1> Update<T1>(object dywhere) where T1 : class => new MySqlUpdate<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
public IDelete<T1> Delete<T1>() where T1 : class => new MySqlDelete<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, null);
public IDelete<T1> Delete<T1>(object dywhere) where T1 : class => new MySqlDelete<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
public IAdo Ado { get; }
public IAop Aop { get; }
public ICodeFirst CodeFirst { get; }
public IDbFirst DbFirst { get; }
public MySqlProvider(string masterConnectionString, string[] slaveConnectionString) {
this.InternalCommonUtils = new MySqlUtils(this);
this.InternalCommonExpression = new MySqlExpression(this.InternalCommonUtils);
public IAdo Ado { get; }
public IAop Aop { get; }
public ICodeFirst CodeFirst { get; }
public IDbFirst DbFirst { get; }
public MySqlProvider(string masterConnectionString, string[] slaveConnectionString)
{
this.InternalCommonUtils = new MySqlUtils(this);
this.InternalCommonExpression = new MySqlExpression(this.InternalCommonUtils);
this.Ado = new MySqlAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString);
this.Aop = new AopProvider();
this.Ado = new MySqlAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString);
this.Aop = new AopProvider();
this.DbFirst = new MySqlDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
this.CodeFirst = new MySqlCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
}
this.DbFirst = new MySqlDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
this.CodeFirst = new MySqlCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
}
internal CommonUtils InternalCommonUtils { get; }
internal CommonExpression InternalCommonExpression { get; }
internal CommonUtils InternalCommonUtils { get; }
internal CommonExpression InternalCommonExpression { get; }
public void Transaction(Action handler) => Ado.Transaction(handler);
public void Transaction(Action handler) => Ado.Transaction(handler);
public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout);
public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout);
~MySqlProvider() {
this.Dispose();
}
bool _isdisposed = false;
public void Dispose() {
if (_isdisposed) return;
(this.Ado as AdoProvider)?.Dispose();
}
}
~MySqlProvider()
{
this.Dispose();
}
bool _isdisposed = false;
public void Dispose()
{
if (_isdisposed) return;
(this.Ado as AdoProvider)?.Dispose();
}
}
}

View File

@ -9,97 +9,119 @@ using System.Linq.Expressions;
using System.Reflection;
using System.Text;
namespace FreeSql.MySql {
namespace FreeSql.MySql
{
class MySqlUtils : CommonUtils {
public MySqlUtils(IFreeSql orm) : base(orm) {
}
class MySqlUtils : CommonUtils
{
public MySqlUtils(IFreeSql orm) : base(orm)
{
}
public override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value };
var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
if (tp != null) {
if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) {
ret.MySqlDbType = MySqlDbType.Text;
if (value != null) ret.Value = (value as MygisGeometry).AsText();
} else
ret.MySqlDbType = (MySqlDbType)tp.Value;
}
_params?.Add(ret);
return ret;
}
public override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value)
{
if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
var ret = new MySqlParameter { ParameterName = QuoteParamterName(parameterName), Value = value };
var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
if (tp != null)
{
if ((MySqlDbType)tp.Value == MySqlDbType.Geometry)
{
ret.MySqlDbType = MySqlDbType.Text;
if (value != null) ret.Value = (value as MygisGeometry).AsText();
}
else
ret.MySqlDbType = (MySqlDbType)tp.Value;
}
_params?.Add(ret);
return ret;
}
public override DbParameter[] GetDbParamtersByObject(string sql, object obj) =>
Utils.GetDbParamtersByObject<MySqlParameter>(sql, obj, "?", (name, type, value) => {
var ret = new MySqlParameter { ParameterName = $"?{name}", Value = value };
var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
if (tp != null) {
if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) {
ret.MySqlDbType = MySqlDbType.Text;
if (value != null) ret.Value = (value as MygisGeometry).AsText();
} else
ret.MySqlDbType = (MySqlDbType)tp.Value;
}
return ret;
});
public override DbParameter[] GetDbParamtersByObject(string sql, object obj) =>
Utils.GetDbParamtersByObject<MySqlParameter>(sql, obj, "?", (name, type, value) =>
{
var ret = new MySqlParameter { ParameterName = $"?{name}", Value = value };
var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
if (tp != null)
{
if ((MySqlDbType)tp.Value == MySqlDbType.Geometry)
{
ret.MySqlDbType = MySqlDbType.Text;
if (value != null) ret.Value = (value as MygisGeometry).AsText();
}
else
ret.MySqlDbType = (MySqlDbType)tp.Value;
}
return ret;
});
public override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args);
public override string QuoteSqlName(string name) {
var nametrim = name.Trim();
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
return nametrim; //原生SQL
return $"`{nametrim.Trim('`').Replace(".", "`.`")}`";
}
public override string TrimQuoteSqlName(string name) {
var nametrim = name.Trim();
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
return nametrim; //原生SQL
return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}";
}
public override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})";
public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})";
public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}";
public override string QuoteWriteParamter(Type type, string paramterName) {
switch (type.FullName) {
case "MygisPoint":
case "MygisLineString":
case "MygisPolygon":
case "MygisMultiPoint":
case "MygisMultiLineString":
case "MygisMultiPolygon": return $"ST_GeomFromText({paramterName})";
}
return paramterName;
}
public override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args);
public override string QuoteSqlName(string name)
{
var nametrim = name.Trim();
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
return nametrim; //原生SQL
return $"`{nametrim.Trim('`').Replace(".", "`.`")}`";
}
public override string TrimQuoteSqlName(string name)
{
var nametrim = name.Trim();
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
return nametrim; //原生SQL
return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}";
}
public override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})";
public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})";
public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}";
public override string QuoteWriteParamter(Type type, string paramterName)
{
switch (type.FullName)
{
case "MygisPoint":
case "MygisLineString":
case "MygisPolygon":
case "MygisMultiPoint":
case "MygisMultiLineString":
case "MygisMultiPolygon": return $"ST_GeomFromText({paramterName})";
}
return paramterName;
}
public override string QuoteReadColumn(Type type, string columnName) {
switch (type.FullName) {
case "MygisPoint":
case "MygisLineString":
case "MygisPolygon":
case "MygisMultiPoint":
case "MygisMultiLineString":
case "MygisMultiPolygon": return $"AsText({columnName})";
}
return columnName;
}
public override string QuoteReadColumn(Type type, string columnName)
{
switch (type.FullName)
{
case "MygisPoint":
case "MygisLineString":
case "MygisPolygon":
case "MygisMultiPoint":
case "MygisMultiLineString":
case "MygisMultiPolygon": return $"AsText({columnName})";
}
return columnName;
}
public override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value) {
if (value == null) return "NULL";
if (type == typeof(byte[])) {
var bytes = value as byte[];
var sb = new StringBuilder().Append("0x");
foreach (var vc in bytes) {
if (vc < 10) sb.Append("0");
sb.Append(vc.ToString("X"));
}
return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]);
} else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) {
var ts = (TimeSpan)value;
value = $"{Math.Floor(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}";
}
return FormatSql("{0}", value, 1);
}
}
public override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, Type type, object value)
{
if (value == null) return "NULL";
if (type == typeof(byte[]))
{
var bytes = value as byte[];
var sb = new StringBuilder().Append("0x");
foreach (var vc in bytes)
{
if (vc < 10) sb.Append("0");
sb.Append(vc.ToString("X"));
}
return sb.ToString(); //val = Encoding.UTF8.GetString(val as byte[]);
}
else if (type == typeof(TimeSpan) || type == typeof(TimeSpan?))
{
var ts = (TimeSpan)value;
value = $"{Math.Floor(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}";
}
return FormatSql("{0}", value, 1);
}
}
}