mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-06-19 20:38:16 +08:00
完善 CodeFirst
This commit is contained in:
@ -11,6 +11,8 @@ namespace FreeSql {
|
||||
DataType _dataType;
|
||||
string _masterConnectionString;
|
||||
string[] _slaveConnectionString;
|
||||
bool _isAutoSyncStructure = false;
|
||||
bool _isSyncStructureToLower = false;
|
||||
|
||||
/// <summary>
|
||||
/// 使用缓存,不指定默认使用内存
|
||||
@ -51,14 +53,35 @@ namespace FreeSql {
|
||||
_slaveConnectionString = slaveConnectionString;
|
||||
return this;
|
||||
}
|
||||
/// <summary>
|
||||
/// 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public FreeSqlBuilder UseAutoSyncStructure() {
|
||||
_isAutoSyncStructure = true;
|
||||
return this;
|
||||
}
|
||||
/// <summary>
|
||||
/// 转小写同步结构
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public FreeSqlBuilder UseSyncStructureToLower() {
|
||||
_isSyncStructureToLower = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IFreeSql Build() {
|
||||
IFreeSql ret = null;
|
||||
switch(_dataType) {
|
||||
case DataType.MySql: return new MySql.MySqlProvider(_cache, null, _masterConnectionString, _slaveConnectionString, _logger);
|
||||
case DataType.SqlServer: return new SqlServer.SqlServerProvider(_cache, null, _masterConnectionString, _slaveConnectionString, _logger);
|
||||
case DataType.PostgreSQL: return new PostgreSQL.PostgreSQLProvider(_cache, null, _masterConnectionString, _slaveConnectionString, _logger);
|
||||
case DataType.MySql: ret = new MySql.MySqlProvider(_cache, null, _masterConnectionString, _slaveConnectionString, _logger); break;
|
||||
case DataType.SqlServer: ret = new SqlServer.SqlServerProvider(_cache, null, _masterConnectionString, _slaveConnectionString, _logger); break;
|
||||
case DataType.PostgreSQL: ret = new PostgreSQL.PostgreSQLProvider(_cache, null, _masterConnectionString, _slaveConnectionString, _logger); break;
|
||||
}
|
||||
return null;
|
||||
if (ret != null) {
|
||||
ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure;
|
||||
ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,11 @@ namespace FreeSql {
|
||||
/// </summary>
|
||||
bool IsAutoSyncStructure { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 转小写同步结构
|
||||
/// </summary>
|
||||
bool IsSyncStructureToLower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 将实体类型与数据库对比,返回DDL语句
|
||||
/// </summary>
|
||||
@ -38,6 +43,6 @@ namespace FreeSql {
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
(int type, string dbtype, string dbtypeFull, bool? isnullable)? GetDbInfo(Type type);
|
||||
(int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,8 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
switch (expCall.Method.Name) {
|
||||
case "Where": this.InternalWhere(expCall.Arguments[0]); break;
|
||||
case "WhereIf":
|
||||
if (_commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false) == "1")
|
||||
var whereIfCond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false);
|
||||
if (whereIfCond == "1" || whereIfCond == "'t'")
|
||||
this.InternalWhere(expCall.Arguments[1]);
|
||||
break;
|
||||
case "GroupBy": this.InternalGroupBy(expCall.Arguments[0]); break;
|
||||
|
@ -66,7 +66,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
if (cols.Any() == false) return this;
|
||||
foreach (var col in cols) {
|
||||
if (col.Column.Attribute.IsNullable) {
|
||||
var replval = col.Column.Attribute.DbDefautValue;
|
||||
var replval = _orm.CodeFirst.GetDbInfo(col.Column.CsType.GenericTypeArguments.FirstOrDefault())?.defaultValue;
|
||||
if (replval == null) continue;
|
||||
var replname = _commonUtils.QuoteSqlName(col.Column.Attribute.Name);
|
||||
expt = expt.Replace(replname, _commonUtils.IsNull(replname, _commonUtils.FormatSql("{0}", replval)));
|
||||
|
@ -22,8 +22,12 @@ namespace FreeSql.Internal {
|
||||
trytb.Type = entity;
|
||||
trytb.Properties = entity.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase);
|
||||
trytb.CsName = entity.Name;
|
||||
trytb.DbName = tbattr?.Name ?? entity.Name;
|
||||
trytb.DbName = (tbattr?.Name ?? entity.Name);
|
||||
trytb.DbOldName = tbattr?.OldName;
|
||||
if (common.CodeFirst.IsSyncStructureToLower) {
|
||||
trytb.DbName = trytb.DbName.ToLower();
|
||||
trytb.DbOldName = trytb.DbOldName?.ToLower();
|
||||
}
|
||||
trytb.SelectFilter = tbattr?.SelectFilter;
|
||||
foreach (var p in trytb.Properties.Values) {
|
||||
var tp = common.CodeFirst.GetDbInfo(p.PropertyType);
|
||||
@ -38,22 +42,23 @@ namespace FreeSql.Internal {
|
||||
IsNullable = tp.Value.isnullable ?? true,
|
||||
IsPrimary = false,
|
||||
};
|
||||
if (string.IsNullOrEmpty(colattr.DbType) == false) colattr.DbType = colattr.DbType.ToUpper();
|
||||
if (tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false;
|
||||
if (string.IsNullOrEmpty(colattr.DbType) == false) colattr.IsNullable = colattr.DbType.Contains("NOT NULL") == false;
|
||||
if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name;
|
||||
if (string.IsNullOrEmpty(colattr.DbType)) colattr.DbType = tp?.dbtypeFull ?? "varchar(255)";
|
||||
colattr.DbType = colattr.DbType.ToUpper();
|
||||
|
||||
if (tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false;
|
||||
if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false;
|
||||
if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name;
|
||||
if (common.CodeFirst.IsSyncStructureToLower) colattr.Name = colattr.Name.ToLower();
|
||||
|
||||
if ((colattr.IsNullable == false || colattr.IsIdentity || colattr.IsPrimary) && colattr.DbType.Contains("NOT NULL") == false) colattr.DbType += " NOT NULL";
|
||||
if (colattr.IsNullable == true && colattr.DbType.Contains("NOT NULL")) colattr.DbType = colattr.DbType.Replace("NOT NULL", "");
|
||||
colattr.DbType = Regex.Replace(colattr.DbType, @"\([^\)]+\)", m => Regex.Replace(m.Groups[0].Value, @"\s", ""));
|
||||
colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type));
|
||||
if (colattr.DbDefautValue == null && p.PropertyType.FullName == "System.String") colattr.DbDefautValue = string.Empty;
|
||||
if (colattr.DbDefautValue == null) {
|
||||
if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue;
|
||||
if (colattr.IsNullable == false && colattr.DbDefautValue == null) {
|
||||
var consturctorType = p.PropertyType.GenericTypeArguments.FirstOrDefault() ?? p.PropertyType;
|
||||
if (consturctorType.GetConstructor(new Type[0]) != null) colattr.DbDefautValue = Activator.CreateInstance(consturctorType);
|
||||
colattr.DbDefautValue = Activator.CreateInstance(consturctorType);
|
||||
}
|
||||
if (colattr.DbDefautValue == null) colattr.DbDefautValue = "";
|
||||
if (colattr.DbDefautValue.GetType().FullName == "System.DateTime") colattr.DbDefautValue = new DateTime(1970, 1, 1);
|
||||
|
||||
var col = new ColumnInfo {
|
||||
Table = trytb,
|
||||
|
@ -1,36 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Reflection;
|
||||
|
||||
public static class MySqlAdoExtensions {
|
||||
public static object GetEnum<T>(this IDataReader dr, int index) {
|
||||
string value = dr.GetString(index);
|
||||
Type t = typeof(T);
|
||||
foreach (var f in t.GetFields())
|
||||
if (f.GetCustomAttribute<DescriptionAttribute>()?.Description == value || f.Name == value) return Enum.Parse(t, f.Name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string ToDescriptionOrString(this Enum item) {
|
||||
string name = item.ToString();
|
||||
DescriptionAttribute desc = item.GetType().GetField(name)?.GetCustomAttribute<DescriptionAttribute>();
|
||||
return desc?.Description ?? name;
|
||||
}
|
||||
public static long ToInt64(this Enum item) {
|
||||
return Convert.ToInt64(item);
|
||||
}
|
||||
public static IEnumerable<T> ToSet<T>(this long value) {
|
||||
List<T> ret = new List<T>();
|
||||
if (value == 0) return ret;
|
||||
Type t = typeof(T);
|
||||
foreach (FieldInfo f in t.GetFields()) {
|
||||
if (f.FieldType != t) continue;
|
||||
object o = Enum.Parse(t, f.Name);
|
||||
long v = (long) o;
|
||||
if ((value & v) == v) ret.Add((T) o);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -290,19 +290,3 @@ public class MygisMultiPolygon : MygisGeometry, IEquatable<MygisMultiPolygon>, I
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
66
FreeSql/MySql/MySqlAdo/MygisTypesExtensions.cs
Normal file
66
FreeSql/MySql/MySqlAdo/MygisTypesExtensions.cs
Normal file
@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测量两个经纬度的距离,返回单位:米
|
||||
/// </summary>
|
||||
/// <param name="that">经纬坐标1</param>
|
||||
/// <param name="point">经纬坐标2</param>
|
||||
/// <returns>返回距离(单位:米)</returns>
|
||||
public static double Distance(this Point that, Point 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 object GetEnum<T>(this IDataReader dr, int index) {
|
||||
string value = dr.GetString(index);
|
||||
Type t = typeof(T);
|
||||
foreach (var f in t.GetFields())
|
||||
if (f.GetCustomAttribute<DescriptionAttribute>()?.Description == value || f.Name == value) return Enum.Parse(t, f.Name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string ToDescriptionOrString(this Enum item) {
|
||||
string name = item.ToString();
|
||||
var desc = item.GetType().GetField(name)?.GetCustomAttribute<DescriptionAttribute>();
|
||||
return desc?.Description ?? name;
|
||||
}
|
||||
public static long ToInt64(this Enum item) {
|
||||
return Convert.ToInt64(item);
|
||||
}
|
||||
public static IEnumerable<T> ToSet<T>(this long value) {
|
||||
List<T> ret = new List<T>();
|
||||
if (value == 0) return ret;
|
||||
Type t = typeof(T);
|
||||
foreach (FieldInfo f in t.GetFields()) {
|
||||
if (f.FieldType != t) continue;
|
||||
object o = Enum.Parse(t, f.Name);
|
||||
long v = (long)o;
|
||||
if ((value & v) == v) ret.Add((T)o);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -23,57 +23,58 @@ namespace FreeSql.MySql {
|
||||
}
|
||||
|
||||
public bool IsAutoSyncStructure { get; set; } = true;
|
||||
public bool IsSyncStructureToLower { get; set; } = false;
|
||||
|
||||
static object _dicCsToDbLock = new object();
|
||||
static Dictionary<string, (MySqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable)> _dicCsToDb = new Dictionary<string, (MySqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable)>() {
|
||||
{ typeof(bool).FullName, (MySqlDbType.Bit, "bit","bit(1) NOT NULL", null, false) },{ typeof(bool?).FullName, (MySqlDbType.Bit, "bit","bit(1)", null, true) },
|
||||
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) },{ typeof(sbyte?).FullName, (MySqlDbType.Byte, "tinyint", "tinyint(3)", false, true) },
|
||||
{ typeof(short).FullName, (MySqlDbType.Int16, "smallint","smallint(6) NOT NULL", false, false) },{ typeof(short?).FullName, (MySqlDbType.Int16, "smallint", "smallint(6)", false, true) },
|
||||
{ typeof(int).FullName, (MySqlDbType.Int32, "int", "int(11) NOT NULL", false, false) },{ typeof(int?).FullName, (MySqlDbType.Int32, "int", "int(11)", false, true) },
|
||||
{ typeof(long).FullName, (MySqlDbType.Int64, "bigint","bigint(20) NOT NULL", false, false) },{ typeof(long?).FullName, (MySqlDbType.Int64, "bigint","bigint(20)", false, true) },
|
||||
{ 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) },{ typeof(byte?).FullName, (MySqlDbType.UByte, "tinyint","tinyint(3) unsigned", true, true) },
|
||||
{ typeof(ushort).FullName, (MySqlDbType.UInt16, "smallint","smallint(5) unsigned NOT NULL", true, false) },{ typeof(ushort?).FullName, (MySqlDbType.UInt16, "smallint", "smallint(5) unsigned", true, true) },
|
||||
{ typeof(uint).FullName, (MySqlDbType.UInt32, "int", "int(10) unsigned NOT NULL", true, false) },{ typeof(uint?).FullName, (MySqlDbType.UInt32, "int", "int(10) unsigned", true, true) },
|
||||
{ typeof(ulong).FullName, (MySqlDbType.UInt64, "bigint", "bigint(20) unsigned NOT NULL", true, false) },{ typeof(ulong?).FullName, (MySqlDbType.UInt64, "bigint", "bigint(20) unsigned", true, true) },
|
||||
{ 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) },{ typeof(double?).FullName, (MySqlDbType.Double, "double", "double", false, true) },
|
||||
{ typeof(float).FullName, (MySqlDbType.Float, "float","float NOT NULL", false, false) },{ typeof(float?).FullName, (MySqlDbType.Float, "float","float", false, true) },
|
||||
{ typeof(decimal).FullName, (MySqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false) },{ typeof(decimal?).FullName, (MySqlDbType.Decimal, "decimal", "decimal(10,2)", false, true) },
|
||||
{ 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) },{ typeof(TimeSpan?).FullName, (MySqlDbType.Time, "time", "time",false, true) },
|
||||
{ typeof(DateTime).FullName, (MySqlDbType.DateTime, "datetime", "datetime NOT NULL", false, false) },{ typeof(DateTime?).FullName, (MySqlDbType.DateTime, "datetime", "datetime", false, true) },
|
||||
{ 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", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (MySqlDbType.DateTime, "datetime", "datetime", false, true, null) },
|
||||
|
||||
{ typeof(byte[]).FullName, (MySqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null) },
|
||||
{ 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)", false, false) },{ typeof(Guid?).FullName, (MySqlDbType.VarChar, "char", "char(36)", false, true) },
|
||||
{ typeof(Guid).FullName, (MySqlDbType.VarChar, "char", "char(36)", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (MySqlDbType.VarChar, "char", "char(36)", false, true, null) },
|
||||
|
||||
{ typeof(MygisPoint).FullName, (MySqlDbType.Geometry, "point", "point", false, null) },
|
||||
{ typeof(MygisLineString).FullName, (MySqlDbType.Geometry, "linestring", "linestring", false, null) },
|
||||
{ typeof(MygisPolygon).FullName, (MySqlDbType.Geometry, "polygon", "polygon", false, null) },
|
||||
{ typeof(MygisMultiPoint).FullName, (MySqlDbType.Geometry, "multipoint","multipoint", false, null) },
|
||||
{ typeof(MygisMultiLineString).FullName, (MySqlDbType.Geometry, "multilinestring","multilinestring", false, null) },
|
||||
{ typeof(MygisMultiPolygon).FullName, (MySqlDbType.Geometry, "multipolygon", "multipolygon", false, 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()}})})) },
|
||||
};
|
||||
|
||||
public (int type, string dbtype, string dbtypeFull, bool? isnullable)? GetDbInfo(Type type) {
|
||||
if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable));
|
||||
public (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));
|
||||
var enumType = type.IsEnum ? type : null;
|
||||
if (enumType == null && type.FullName.StartsWith("System.Nullable`1[") && 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) :
|
||||
(MySqlDbType.Enum, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true);
|
||||
(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);
|
||||
return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -218,26 +219,22 @@ where a.table_schema in ({0}) and a.table_name in ({1})".FormatMySql(tboldname ?
|
||||
}
|
||||
sb.Append("\r\n) Engine=InnoDB CHARACTER SET utf8;\r\n");
|
||||
sb.Append("INSERT INTO ").Append(tmptablename).Append(" (");
|
||||
foreach (var tbcol in tb.Columns.Values) {
|
||||
if (tbstruct.ContainsKey(tbcol.Attribute.Name) ||
|
||||
string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.ContainsKey(tbcol.Attribute.OldName)) { //导入旧表存在的字段
|
||||
sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).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)) {
|
||||
var insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column);
|
||||
insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column);
|
||||
if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) {
|
||||
//var tbcoldbtype = tbcol.Attribute.DbType.Split(' ').First();
|
||||
//insertvalue = $"cast({insertvalue} as {tbcoldbtype})";
|
||||
//insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})";
|
||||
}
|
||||
if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) {
|
||||
if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable)
|
||||
insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")})";
|
||||
}
|
||||
sb.Append(insertvalue).Append(", ");
|
||||
}
|
||||
} else if (tbcol.Attribute.IsNullable == false)
|
||||
insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''");
|
||||
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");
|
||||
|
@ -173,7 +173,7 @@ namespace FreeSql.MySql {
|
||||
|
||||
case "IsLeapYear":
|
||||
var isLeapYearArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100 <> 0 OR ({isLeapYearArgs1})%400 = 0)";
|
||||
return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)";
|
||||
|
||||
case "Parse": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as datetime)";
|
||||
case "ParseExact":
|
||||
|
@ -14,6 +14,7 @@ namespace FreeSql.MySql {
|
||||
|
||||
internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, object value) {
|
||||
if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
|
||||
else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower();
|
||||
MySqlParameter ret = null;
|
||||
if (value == null) ret = new MySqlParameter { ParameterName = $"{parameterName}", Value = DBNull.Value };
|
||||
else {
|
||||
@ -42,7 +43,7 @@ namespace FreeSql.MySql {
|
||||
|
||||
internal override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args);
|
||||
internal override string QuoteSqlName(string name) => $"`{name.Trim('`').Replace(".", "`.`")}`";
|
||||
internal override string QuoteParamterName(string name) => $"?{name}";
|
||||
internal override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
|
||||
internal override string IsNull(string sql, object value) => $"ifnull({sql}, {value})";
|
||||
internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"concat({left}, {right})";
|
||||
}
|
||||
|
@ -36,13 +36,11 @@ namespace FreeSql.PostgreSQL {
|
||||
return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'");
|
||||
else if (param is DateTime?)
|
||||
return string.Concat("'", (param as DateTime?).Value.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'");
|
||||
else if (param is TimeSpan) {
|
||||
var ts = (TimeSpan)param;
|
||||
return string.Concat("'", ts.Ticks > 0 ? "" : "-", ts.TotalHours, dt1970.AddTicks(Math.Abs(ts.Ticks)).ToString(":mm:ss.ffffff"), "'");
|
||||
} else if (param is TimeSpan) {
|
||||
var ts = (param as TimeSpan?).Value;
|
||||
return string.Concat("'", ts.Ticks > 0 ? "" : "-", ts.TotalHours, dt1970.AddTicks(Math.Abs(ts.Ticks)).ToString(":mm:ss.ffffff"), "'");
|
||||
} else if (param is IEnumerable) {
|
||||
else if (param is TimeSpan)
|
||||
return ((TimeSpan)param).Ticks / 10;
|
||||
else if (param is TimeSpan?)
|
||||
return (param as TimeSpan?).Value.Ticks / 10;
|
||||
else if (param is IEnumerable) {
|
||||
var sb = new StringBuilder();
|
||||
var ie = param as IEnumerable;
|
||||
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z));
|
||||
|
@ -1,4 +1,5 @@
|
||||
using NpgsqlTypes;
|
||||
using Npgsql.LegacyPostgis;
|
||||
using NpgsqlTypes;
|
||||
using System;
|
||||
|
||||
public static partial class PostgreSQLTypesExtensions {
|
||||
@ -15,4 +16,18 @@ public static partial class PostgreSQLTypesExtensions {
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测量两个经纬度的距离,返回单位:米
|
||||
/// </summary>
|
||||
/// <param name="that">经纬坐标1</param>
|
||||
/// <param name="point">经纬坐标2</param>
|
||||
/// <returns>返回距离(单位:米)</returns>
|
||||
public static double Distance(this PostgisPoint that, PostgisPoint 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;
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace FreeSql.PostgreSQL {
|
||||
|
||||
@ -27,89 +28,91 @@ namespace FreeSql.PostgreSQL {
|
||||
}
|
||||
|
||||
public bool IsAutoSyncStructure { get; set; } = true;
|
||||
public bool IsSyncStructureToLower { get; set; } = false;
|
||||
|
||||
static object _dicCsToDbLock = new object();
|
||||
static Dictionary<string, (NpgsqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable)> _dicCsToDb = new Dictionary<string, (NpgsqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable)>() {
|
||||
static Dictionary<string, (NpgsqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (NpgsqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
|
||||
|
||||
{ typeof(sbyte).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false) },{ typeof(sbyte?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true) },
|
||||
{ typeof(short).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false) },{ typeof(short?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true) },
|
||||
{ typeof(int).FullName, (NpgsqlDbType.Integer, "int4","int4 NOT NULL", false, false) },{ typeof(int?).FullName, (NpgsqlDbType.Integer, "int4", "int4", false, true) },
|
||||
{ typeof(long).FullName, (NpgsqlDbType.Bigint, "int8","int8 NOT NULL", false, false) },{ typeof(long?).FullName, (NpgsqlDbType.Bigint, "int8", "int8", false, true) },
|
||||
{ typeof(sbyte).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true, null) },
|
||||
{ typeof(short).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(short?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true, null) },
|
||||
{ typeof(int).FullName, (NpgsqlDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(int?).FullName, (NpgsqlDbType.Integer, "int4", "int4", false, true, null) },
|
||||
{ typeof(long).FullName, (NpgsqlDbType.Bigint, "int8","int8 NOT NULL", false, false, 0) },{ typeof(long?).FullName, (NpgsqlDbType.Bigint, "int8", "int8", false, true, null) },
|
||||
|
||||
{ typeof(byte).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false) },{ typeof(byte?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true) },
|
||||
{ typeof(ushort).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false) },{ typeof(ushort?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true) },
|
||||
{ typeof(uint).FullName, (NpgsqlDbType.Integer, "int4","int4 NOT NULL", false, false) },{ typeof(uint?).FullName, (NpgsqlDbType.Integer, "int4", "int4", false, true) },
|
||||
{ typeof(ulong).FullName, (NpgsqlDbType.Bigint, "int8","int8 NOT NULL", false, false) },{ typeof(ulong?).FullName, (NpgsqlDbType.Bigint, "int8", "int8", false, true) },
|
||||
{ typeof(byte).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(byte?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true, null) },
|
||||
{ typeof(ushort).FullName, (NpgsqlDbType.Smallint, "int2","int2 NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, (NpgsqlDbType.Smallint, "int2", "int2", false, true, null) },
|
||||
{ typeof(uint).FullName, (NpgsqlDbType.Integer, "int4","int4 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, (NpgsqlDbType.Integer, "int4", "int4", false, true, null) },
|
||||
{ typeof(ulong).FullName, (NpgsqlDbType.Bigint, "int8","int8 NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, (NpgsqlDbType.Bigint, "int8", "int8", false, true, null) },
|
||||
|
||||
{ typeof(float).FullName, (NpgsqlDbType.Real, "float4","float4 NOT NULL", false, false) },{ typeof(float?).FullName, (NpgsqlDbType.Real, "float4", "float4", false, true) },
|
||||
{ typeof(double).FullName, (NpgsqlDbType.Double, "float8","float8 NOT NULL", false, false) },{ typeof(double?).FullName, (NpgsqlDbType.Double, "float8", "float8", false, true) },
|
||||
{ typeof(decimal).FullName, (NpgsqlDbType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false) },{ typeof(decimal?).FullName, (NpgsqlDbType.Numeric, "numeric", "numeric(10,2)", false, true) },
|
||||
{ typeof(float).FullName, (NpgsqlDbType.Real, "float4","float4 NOT NULL", false, false, 0) },{ typeof(float?).FullName, (NpgsqlDbType.Real, "float4", "float4", false, true, null) },
|
||||
{ typeof(double).FullName, (NpgsqlDbType.Double, "float8","float8 NOT NULL", false, false, 0) },{ typeof(double?).FullName, (NpgsqlDbType.Double, "float8", "float8", false, true, null) },
|
||||
{ typeof(decimal).FullName, (NpgsqlDbType.Numeric, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (NpgsqlDbType.Numeric, "numeric", "numeric(10,2)", false, true, null) },
|
||||
|
||||
{ typeof(string).FullName, (NpgsqlDbType.Varchar, "varchar", "varchar(255)", false, null) },
|
||||
{ typeof(string).FullName, (NpgsqlDbType.Varchar, "varchar", "varchar(255)", false, null, "") },
|
||||
|
||||
{ typeof(TimeSpan).FullName, (NpgsqlDbType.Time, "time","time NOT NULL", false, false) },{ typeof(TimeSpan?).FullName, (NpgsqlDbType.Time, "time", "time",false, true) },
|
||||
{ typeof(DateTime).FullName, (NpgsqlDbType.Timestamp, "timestamp", "timestamp NOT NULL", false, false) },{ typeof(DateTime?).FullName, (NpgsqlDbType.Timestamp, "timestamp", "timestamp", false, true) },
|
||||
{ typeof(TimeSpan).FullName, (NpgsqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (NpgsqlDbType.Time, "time", "time",false, true, null) },
|
||||
{ typeof(DateTime).FullName, (NpgsqlDbType.Timestamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (NpgsqlDbType.Timestamp, "timestamp", "timestamp", false, true, null) },
|
||||
|
||||
{ typeof(bool).FullName, (NpgsqlDbType.Boolean, "bool","bool NOT NULL", null, false) },{ typeof(bool?).FullName, (NpgsqlDbType.Bit, "bool","bool", null, true) },
|
||||
{ typeof(Byte[]).FullName, (NpgsqlDbType.Bytea, "bytea", "bytea", false, null) },
|
||||
{ typeof(BitArray).FullName, (NpgsqlDbType.Varbit, "varbit", "varbit(64)", false, null) },
|
||||
{ typeof(bool).FullName, (NpgsqlDbType.Boolean, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, (NpgsqlDbType.Bit, "bool","bool", null, true, null) },
|
||||
{ typeof(Byte[]).FullName, (NpgsqlDbType.Bytea, "bytea", "bytea", false, null, new byte[0]) },
|
||||
{ typeof(BitArray).FullName, (NpgsqlDbType.Varbit, "varbit", "varbit(64)", false, null, new BitArray(new byte[64])) },
|
||||
|
||||
{ typeof(NpgsqlPoint).FullName, (NpgsqlDbType.Point, "point", "point NOT NULL", false, false) },{ typeof(NpgsqlPoint?).FullName, (NpgsqlDbType.Point, "point", "point", false, true) },
|
||||
{ typeof(NpgsqlLine).FullName, (NpgsqlDbType.Line, "line", "line NOT NULL", false, false) },{ typeof(NpgsqlLine?).FullName, (NpgsqlDbType.Line, "line", "line", false, true) },
|
||||
{ typeof(NpgsqlLSeg).FullName, (NpgsqlDbType.LSeg, "lseg", "lseg NOT NULL", false, false) },{ typeof(NpgsqlLSeg?).FullName, (NpgsqlDbType.LSeg, "lseg", "lseg", false, true) },
|
||||
{ typeof(NpgsqlBox).FullName, (NpgsqlDbType.Box, "box", "box NOT NULL", false, false) },{ typeof(NpgsqlBox?).FullName, (NpgsqlDbType.Box, "box", "box", false, true) },
|
||||
{ typeof(NpgsqlPath).FullName, (NpgsqlDbType.Path, "path", "path NOT NULL", false, false) },{ typeof(NpgsqlPath?).FullName, (NpgsqlDbType.Path, "path", "path", false, true) },
|
||||
{ typeof(NpgsqlPolygon).FullName, (NpgsqlDbType.Polygon, "polygon", "polygon NOT NULL", false, false) },{ typeof(NpgsqlPolygon?).FullName, (NpgsqlDbType.Polygon, "polygon", "polygon", false, true) },
|
||||
{ typeof(NpgsqlCircle).FullName, (NpgsqlDbType.Circle, "circle", "circle NOT NULL", false, false) },{ typeof(NpgsqlCircle?).FullName, (NpgsqlDbType.Circle, "circle", "circle", false, true) },
|
||||
{ typeof(NpgsqlPoint).FullName, (NpgsqlDbType.Point, "point", "point NOT NULL", false, false, new NpgsqlPoint()) },{ typeof(NpgsqlPoint?).FullName, (NpgsqlDbType.Point, "point", "point", false, true, null) },
|
||||
{ typeof(NpgsqlLine).FullName, (NpgsqlDbType.Line, "line", "line NOT NULL", false, false, new NpgsqlLine()) },{ typeof(NpgsqlLine?).FullName, (NpgsqlDbType.Line, "line", "line", false, true, null) },
|
||||
{ typeof(NpgsqlLSeg).FullName, (NpgsqlDbType.LSeg, "lseg", "lseg NOT NULL", false, false, new NpgsqlLSeg()) },{ typeof(NpgsqlLSeg?).FullName, (NpgsqlDbType.LSeg, "lseg", "lseg", false, true, null) },
|
||||
{ typeof(NpgsqlBox).FullName, (NpgsqlDbType.Box, "box", "box NOT NULL", false, false, new NpgsqlBox()) },{ typeof(NpgsqlBox?).FullName, (NpgsqlDbType.Box, "box", "box", false, true, null) },
|
||||
{ typeof(NpgsqlPath).FullName, (NpgsqlDbType.Path, "path", "path NOT NULL", false, false, new NpgsqlPath()) },{ typeof(NpgsqlPath?).FullName, (NpgsqlDbType.Path, "path", "path", false, true, null) },
|
||||
{ typeof(NpgsqlPolygon).FullName, (NpgsqlDbType.Polygon, "polygon", "polygon NOT NULL", false, false, new NpgsqlPolygon()) },{ typeof(NpgsqlPolygon?).FullName, (NpgsqlDbType.Polygon, "polygon", "polygon", false, true, null) },
|
||||
{ typeof(NpgsqlCircle).FullName, (NpgsqlDbType.Circle, "circle", "circle NOT NULL", false, false, new NpgsqlCircle()) },{ typeof(NpgsqlCircle?).FullName, (NpgsqlDbType.Circle, "circle", "circle", false, true, null) },
|
||||
|
||||
{ typeof((IPAddress Address, int Subnet)).FullName, (NpgsqlDbType.Cidr, "cidr", "cidr NOT NULL", false, false) },{ typeof((IPAddress Address, int Subnet)?).FullName, (NpgsqlDbType.Cidr, "cidr", "cidr", false, true) },
|
||||
{ typeof(IPAddress).FullName, (NpgsqlDbType.Inet, "inet", "inet", false, null) },
|
||||
{ typeof(PhysicalAddress).FullName, (NpgsqlDbType.MacAddr, "macaddr", "macaddr", false, null) },
|
||||
{ typeof((IPAddress Address, int Subnet)).FullName, (NpgsqlDbType.Cidr, "cidr", "cidr NOT NULL", false, false, (IPAddress.None, 0)) },{ typeof((IPAddress Address, int Subnet)?).FullName, (NpgsqlDbType.Cidr, "cidr", "cidr", false, true, null) },
|
||||
{ typeof(IPAddress).FullName, (NpgsqlDbType.Inet, "inet", "inet", false, null, IPAddress.None) },
|
||||
{ typeof(PhysicalAddress).FullName, (NpgsqlDbType.MacAddr, "macaddr", "macaddr", false, null, PhysicalAddress.None) },
|
||||
|
||||
{ typeof(JToken).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null) },
|
||||
{ typeof(JObject).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null) },
|
||||
{ typeof(JArray).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null) },
|
||||
{ typeof(Guid).FullName, (NpgsqlDbType.Uuid, "uuid", "uuid NOT NULL", false, false) },{ typeof(Guid?).FullName, (NpgsqlDbType.Uuid, "uuid", "uuid", false, true) },
|
||||
{ typeof(JToken).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JToken.Parse("{}")) },
|
||||
{ typeof(JObject).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JObject.Parse("{}")) },
|
||||
{ typeof(JArray).FullName, (NpgsqlDbType.Jsonb, "jsonb", "jsonb", false, null, JArray.Parse("[]")) },
|
||||
{ typeof(Guid).FullName, (NpgsqlDbType.Uuid, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (NpgsqlDbType.Uuid, "uuid", "uuid", false, true, null) },
|
||||
|
||||
{ typeof(NpgsqlRange<int>).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Integer, "int4range", "int4range NOT NULL", false, false) },{ typeof(NpgsqlRange<int>?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Integer, "int4range", "int4range", false, true) },
|
||||
{ typeof(NpgsqlRange<long>).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Bigint, "int8range", "int8range NOT NULL", false, false) },{ typeof(NpgsqlRange<long>?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Bigint, "int8range", "int8range", false, true) },
|
||||
{ typeof(NpgsqlRange<decimal>).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Numeric, "numrange", "numrange NOT NULL", false, false) },{ typeof(NpgsqlRange<decimal>?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Numeric, "numrange", "numrange", false, true) },
|
||||
{ typeof(NpgsqlRange<DateTime>).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange NOT NULL", false, false) },{ typeof(NpgsqlRange<DateTime>?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange", false, true) },
|
||||
{ typeof(NpgsqlRange<int>).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Integer, "int4range", "int4range NOT NULL", false, false, NpgsqlRange<int>.Empty) },{ typeof(NpgsqlRange<int>?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Integer, "int4range", "int4range", false, true, null) },
|
||||
{ typeof(NpgsqlRange<long>).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Bigint, "int8range", "int8range NOT NULL", false, false, NpgsqlRange<long>.Empty) },{ typeof(NpgsqlRange<long>?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Bigint, "int8range", "int8range", false, true, null) },
|
||||
{ typeof(NpgsqlRange<decimal>).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Numeric, "numrange", "numrange NOT NULL", false, false, NpgsqlRange<decimal>.Empty) },{ typeof(NpgsqlRange<decimal>?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Numeric, "numrange", "numrange", false, true, null) },
|
||||
{ typeof(NpgsqlRange<DateTime>).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange NOT NULL", false, false, NpgsqlRange<DateTime>.Empty) },{ typeof(NpgsqlRange<DateTime>?).FullName, (NpgsqlDbType.Range | NpgsqlDbType.Timestamp, "tsrange", "tsrange", false, true, null) },
|
||||
|
||||
{ typeof(Dictionary<string, string>).FullName, (NpgsqlDbType.Hstore, "hstore", "hstore", false, null) },
|
||||
{ typeof(PostgisPoint).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null) },
|
||||
{ typeof(PostgisLineString).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null) },
|
||||
{ typeof(PostgisPolygon).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null) },
|
||||
{ typeof(PostgisMultiPoint).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null) },
|
||||
{ typeof(PostgisMultiLineString).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null) },
|
||||
{ typeof(PostgisMultiPolygon).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null) },
|
||||
{ typeof(PostgisGeometry).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null) },
|
||||
{ typeof(PostgisGeometryCollection).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null) },
|
||||
{ typeof(Dictionary<string, string>).FullName, (NpgsqlDbType.Hstore, "hstore", "hstore", false, null, new Dictionary<string, string>()) },
|
||||
{ typeof(PostgisPoint).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPoint(0, 0)) },
|
||||
{ typeof(PostgisLineString).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) })) },
|
||||
{ typeof(PostgisPolygon).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } })) },
|
||||
{ typeof(PostgisMultiPoint).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiPoint(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) })) },
|
||||
{ typeof(PostgisMultiLineString).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiLineString(new[]{new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }),new PostgisLineString(new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }) })) },
|
||||
{ typeof(PostgisMultiPolygon).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisMultiPolygon(new[]{new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } }),new PostgisPolygon(new []{new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) }, new []{new Coordinate2D(0, 0),new Coordinate2D(0, 0) } }) })) },
|
||||
{ typeof(PostgisGeometry).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisPoint(0, 0)) },
|
||||
{ typeof(PostgisGeometryCollection).FullName, (NpgsqlDbType.Geometry, "geometry", "geometry", false, null, new PostgisGeometryCollection(new[]{new PostgisPoint(0, 0),new PostgisPoint(0, 0) })) },
|
||||
};
|
||||
|
||||
public (int type, string dbtype, string dbtypeFull, bool? isnullable)? GetDbInfo(Type type) {
|
||||
var elementType = type.IsArray ? type.GetElementType() : type;
|
||||
public (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) {
|
||||
var isarray = type.FullName != "System.Byte[]" && type.IsArray;
|
||||
var elementType = isarray ? type.GetElementType() : type;
|
||||
var info = GetDbInfoNoneArray(elementType);
|
||||
if (info == null) return null;
|
||||
if (type.IsArray == false) return ((int)info.Value.type, info.Value.dbtype, info.Value.dbtypeFull, info.Value.isnullable);
|
||||
var dbype = $"{info.Value.dbtype}[]";
|
||||
return ((int)(info.Value.type | NpgsqlDbType.Array), dbype, info.Value.dbtypeFull.Replace(info.Value.dbtype, dbype), info.Value.isnullable);
|
||||
if (isarray == false) return ((int)info.Value.type, info.Value.dbtype, info.Value.dbtypeFull, info.Value.isnullable, info.Value.defaultValue);
|
||||
var dbtypefull = Regex.Replace(info.Value.dbtypeFull, $@"{info.Value.dbtype}(\s*\([^\)]+\))?", "$0[]");
|
||||
return ((int)(info.Value.type | NpgsqlDbType.Array), $"{info.Value.dbtype}[]", dbtypefull, info.Value.isnullable, Array.CreateInstance(elementType, 0));
|
||||
}
|
||||
(NpgsqlDbType type, string dbtype, string dbtypeFull, bool? isnullable)? GetDbInfoNoneArray(Type type) {
|
||||
if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (NpgsqlDbType, string, string, bool?)?((trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable));
|
||||
(NpgsqlDbType type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfoNoneArray(Type type) {
|
||||
if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (NpgsqlDbType, string, string, bool?, object)?((trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue));
|
||||
var enumType = type.IsEnum ? type : null;
|
||||
if (enumType == null && type.FullName.StartsWith("System.Nullable`1[") && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First();
|
||||
if (enumType != null) {
|
||||
var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ?
|
||||
(NpgsqlDbType.Bigint, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true) :
|
||||
(NpgsqlDbType.Integer, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true);
|
||||
(NpgsqlDbType.Bigint, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) :
|
||||
(NpgsqlDbType.Integer, "int4", $"int4{(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 (newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5);
|
||||
return (newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -143,7 +146,7 @@ namespace FreeSql.PostgreSQL {
|
||||
//创建表
|
||||
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(" ").Append(tbcol.Attribute.DbType.ToUpper()).Append(",");
|
||||
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(",");
|
||||
if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, true));
|
||||
}
|
||||
if (tb.Primarys.Any() == false)
|
||||
@ -171,7 +174,7 @@ namespace FreeSql.PostgreSQL {
|
||||
a.attname,
|
||||
t.typname,
|
||||
case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len,
|
||||
case when t.typelem = 0 then t.typname else t2.typname end,
|
||||
case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end,
|
||||
case when a.attnotnull then '0' else '1' end as is_nullable,
|
||||
e.adsrc,
|
||||
a.attndims
|
||||
@ -185,34 +188,51 @@ inner join pg_namespace ns on ns.oid = c.relnamespace
|
||||
inner join pg_namespace ns2 on ns2.oid = t.typnamespace
|
||||
where ns.nspname = {0} and c.relname = {1}".FormatPostgreSQL(tboldname ?? tbname);
|
||||
var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
|
||||
var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => new {
|
||||
column = string.Concat(a[0]),
|
||||
sqlType = string.Concat(a[3], long.Parse(string.Concat(a[6])) > 0 ? "[]" : ""),
|
||||
max_length = long.Parse(string.Concat(a[2])),
|
||||
is_nullable = string.Concat(a[4]) == "1",
|
||||
is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"),
|
||||
attndims = long.Parse(string.Concat(a[6]))
|
||||
}, StringComparer.CurrentCultureIgnoreCase);
|
||||
var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => {
|
||||
var attndims = int.Parse(string.Concat(a[6]));
|
||||
var type = string.Concat(a[1]);
|
||||
var sqlType = string.Concat(a[3]);
|
||||
var max_length = long.Parse(string.Concat(a[2]));
|
||||
switch (sqlType) {
|
||||
case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break;
|
||||
default: max_length *= 8; break;
|
||||
}
|
||||
if (type.StartsWith("_")) {
|
||||
type = type.Substring(1);
|
||||
if (attndims == 0) attndims++;
|
||||
}
|
||||
if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1);
|
||||
return new {
|
||||
column = string.Concat(a[0]),
|
||||
sqlType = string.Concat(sqlType),
|
||||
max_length = long.Parse(string.Concat(a[2])),
|
||||
is_nullable = string.Concat(a[4]) == "1",
|
||||
is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"),
|
||||
attndims
|
||||
};
|
||||
}, StringComparer.CurrentCultureIgnoreCase);
|
||||
|
||||
if (istmpatler == false) {
|
||||
foreach (var tbcol in tb.Columns.Values) {
|
||||
if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) ||
|
||||
string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) {
|
||||
if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false ||
|
||||
tbcol.Attribute.IsNullable != tbstructcol.is_nullable) {
|
||||
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.ToUpper()).Append(";\r\n");
|
||||
break;
|
||||
}
|
||||
if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity));
|
||||
if (tbstructcol.column == tbcol.Attribute.OldName) {
|
||||
tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0))
|
||||
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n");
|
||||
if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable)
|
||||
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable ? "DROP" : "SET").Append(" NOT NULL;\r\n");
|
||||
if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity)
|
||||
seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity));
|
||||
if (tbstructcol.column == tbcol.Attribute.OldName)
|
||||
//修改列名
|
||||
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.OldName)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
//添加列
|
||||
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.ToUpper()).Append(";\r\n");
|
||||
if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity));
|
||||
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n");
|
||||
sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(_commonUtils.FormatSql(" = {0};\r\n", tbcol.Attribute.DbDefautValue));
|
||||
if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n");
|
||||
if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity));
|
||||
}
|
||||
}
|
||||
if (istmpatler == false) {
|
||||
@ -225,7 +245,7 @@ where ns.nspname = {0} and c.relname = {1}".FormatPostgreSQL(tboldname ?? tbname
|
||||
//创建临时表
|
||||
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(" ").Append(tbcol.Attribute.DbType.ToUpper()).Append(",");
|
||||
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(",");
|
||||
if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, true));
|
||||
}
|
||||
if (tb.Primarys.Any() == false)
|
||||
@ -237,26 +257,21 @@ where ns.nspname = {0} and c.relname = {1}".FormatPostgreSQL(tboldname ?? tbname
|
||||
}
|
||||
sb.Append("\r\n) WITH (OIDS=FALSE);\r\n");
|
||||
sb.Append("INSERT INTO ").Append(tmptablename).Append(" (");
|
||||
foreach (var tbcol in tb.Columns.Values) {
|
||||
if (tbstruct.ContainsKey(tbcol.Attribute.Name) ||
|
||||
string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.ContainsKey(tbcol.Attribute.OldName)) { //导入旧表存在的字段
|
||||
sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).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)) {
|
||||
var insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column);
|
||||
if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) {
|
||||
var tbcoldbtype = tbcol.Attribute.DbType.Split(' ').First();
|
||||
insertvalue = $"cast({insertvalue} as {tbcoldbtype})";
|
||||
}
|
||||
if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) {
|
||||
insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")})";
|
||||
}
|
||||
sb.Append(insertvalue).Append(", ");
|
||||
}
|
||||
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 = $"coalesce({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")})";
|
||||
} else if (tbcol.Attribute.IsNullable == false)
|
||||
insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''");
|
||||
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");
|
||||
|
@ -11,11 +11,17 @@ namespace FreeSql.PostgreSQL {
|
||||
public PostgreSQLExpression(CommonUtils common) : base(common) { }
|
||||
|
||||
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||
if (exp.Expression == null) {
|
||||
switch (exp.Member.Name) {
|
||||
case "Empty": return "''";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
switch (exp.Member.Name) {
|
||||
case "Length": return $"char_length({left})";
|
||||
}
|
||||
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
|
||||
return null;
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||
if (exp.Expression == null) {
|
||||
@ -23,10 +29,15 @@ namespace FreeSql.PostgreSQL {
|
||||
case "Now": return "current_timestamp";
|
||||
case "UtcNow": return "(current_timestamp at time zone 'UTC')";
|
||||
case "Today": return "current_date";
|
||||
case "MinValue": return "'0001/1/1 0:00:00'::timestamp";
|
||||
case "MaxValue": return "'9999/12/31 23:59:59'::timestamp";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
switch (exp.Member.Name) {
|
||||
case "Date": return $"({left})::date";
|
||||
case "TimeOfDay": return $"(extract(epoch from ({left})::time)*1000000)";
|
||||
case "DayOfWeek": return $"extract(dow from ({left})::timestamp)";
|
||||
case "Day": return $"extract(day from ({left})::timestamp)";
|
||||
case "DayOfYear": return $"extract(doy from ({left})::timestamp)";
|
||||
@ -35,27 +46,35 @@ namespace FreeSql.PostgreSQL {
|
||||
case "Hour": return $"extract(hour from ({left})::timestamp)";
|
||||
case "Minute": return $"extract(minute from ({left})::timestamp)";
|
||||
case "Second": return $"extract(second from ({left})::timestamp)";
|
||||
case "Millisecond": return $"(extract(milliseconds from ({left})::timestamp) - extract(second from ({left})::timestamp) * 1000)";
|
||||
case "Ticks": return $"(extract(epoch from ({left})::timestamp) * 10000000 + 621355968000000000)";
|
||||
case "Millisecond": return $"(extract(milliseconds from ({left})::timestamp)-extract(second from ({left})::timestamp)*1000)";
|
||||
case "Ticks": return $"(extract(epoch from ({left})::timestamp)*10000000+621355968000000000)";
|
||||
}
|
||||
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
|
||||
return null;
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||
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, _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
switch (exp.Member.Name) {
|
||||
case "Days": return $"floor(extract(epoch from ({left})::interval) / {60 * 60 * 24})";
|
||||
case "Hours": return $"extract(hour from ({left})::interval)";
|
||||
case "Milliseconds": return $"(extract(milliseconds from ({left})::interval) - extract(second from ({left})::interval) * 1000)";
|
||||
case "Minutes": return $"extract(minute from ({left})::interval)";
|
||||
case "Seconds": return $"extract(second from ({left})::interval)";
|
||||
case "Ticks": return $"(extract(epoch from ({left})::interval) * 10000000)";
|
||||
case "TotalDays": return $"floor(extract(epoch from ({left})::interval) / {60 * 60 * 24})";
|
||||
case "TotalHours": return $"floor(extract(epoch from ({left})::interval) / {60 * 60})";
|
||||
case "TotalMilliseconds": return $"(epoch from ({left})::interval + extract(milliseconds from ({left})::interval) - extract(second from ({left})::interval) * 1000)";
|
||||
case "TotalMinutes": return $"floor(extract(epoch from ({left})::interval) / 60)";
|
||||
case "TotalSeconds": return $"extract(epoch from ({left})::interval)";
|
||||
case "Days": return $"floor(({left})/{(long)1000000 * 60 * 60 * 24})";
|
||||
case "Hours": return $"floor(({left})/{(long)1000000 * 60 * 60}%24)";
|
||||
case "Milliseconds": return $"(floor(({left})/1000)::int8%1000)";
|
||||
case "Minutes": return $"(floor(({left})/{(long)1000000 * 60})::int8%60)";
|
||||
case "Seconds": return $"(floor(({left})/1000000)::int8%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)";
|
||||
}
|
||||
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
|
||||
return null;
|
||||
}
|
||||
|
||||
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||
@ -80,10 +99,10 @@ namespace FreeSql.PostgreSQL {
|
||||
case "Substring":
|
||||
var substrArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
|
||||
else substrArgs1 += " + 1";
|
||||
else substrArgs1 += "+1";
|
||||
if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})";
|
||||
return $"substr({left}, {substrArgs1}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)})";
|
||||
case "IndexOf": return $"(strpos({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)}) - 1)";
|
||||
case "IndexOf": return $"(strpos({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})-1)";
|
||||
case "PadLeft":
|
||||
if (exp.Arguments.Count == 1) return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})";
|
||||
return $"lpad({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)})";
|
||||
@ -98,7 +117,8 @@ namespace FreeSql.PostgreSQL {
|
||||
if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
|
||||
if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
|
||||
}
|
||||
var trimArg = "";
|
||||
var trimArg1 = "";
|
||||
var trimArg2 = "";
|
||||
foreach (var argsTrim02 in exp.Arguments) {
|
||||
var argsTrim01s = new[] { argsTrim02 };
|
||||
if (argsTrim02.NodeType == ExpressionType.NewArrayInit) {
|
||||
@ -106,17 +126,18 @@ namespace FreeSql.PostgreSQL {
|
||||
argsTrim01s = arritem.Expressions.ToArray();
|
||||
}
|
||||
foreach (var argsTrim01 in argsTrim01s) {
|
||||
var trimChr = ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, tbtype, isQuoteName).Trim('"');
|
||||
if (trimChr.Length == 1) trimArg += trimChr;
|
||||
else trimArg += $" || ({trimArg})";
|
||||
var trimChr = ExpressionLambdaToSql(argsTrim01, _tables, _selectColumnMap, tbtype, isQuoteName).Trim('\'');
|
||||
if (trimChr.Length == 1) trimArg1 += trimChr;
|
||||
else trimArg2 += $" || ({trimChr})";
|
||||
}
|
||||
}
|
||||
if (exp.Method.Name == "Trim") left = $"trim({left}, {trimArg})";
|
||||
if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {trimArg})";
|
||||
if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {trimArg})";
|
||||
if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
|
||||
if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
|
||||
if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
|
||||
return left;
|
||||
case "Replace": return $"replace({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)}, {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)})";
|
||||
case "CompareTo": return $"strcmp({left}, {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})";
|
||||
case "CompareTo": return $"case when {left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} then 0 when {left} > {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} then 1 else -1 end";
|
||||
case "Equals": return $"({left} = ({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::varchar)";
|
||||
}
|
||||
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
|
||||
}
|
||||
@ -146,54 +167,94 @@ namespace FreeSql.PostgreSQL {
|
||||
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
var args1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
switch (exp.Method.Name) {
|
||||
case "Add": return $"(({left})::timestamp + ({args1})::interval)";
|
||||
case "AddDays": return $"(({left})::timestamp + (({args1}) || ' day')::interval)";
|
||||
case "AddHours": return $"(({left})::timestamp + (({args1}) || ' hour')::interval)";
|
||||
case "AddMilliseconds": return $"(({left})::timestamp + (({args1}) || ' milliseconds')::interval)";
|
||||
case "AddMinutes": return $"(({left})::timestamp + (({args1}) || ' minute')::interval)";
|
||||
case "AddMonths": return $"(({left})::timestamp + (({args1}) || ' month')::interval)";
|
||||
case "AddSeconds": return $"(({left})::timestamp + (({args1}) || ' second')::interval)";
|
||||
case "AddTicks": return $"(({left})::timestamp + (({args1}) / 10 || ' microseconds')::interval)";
|
||||
case "AddYears": return $"(({left})::timestamp + (({args1}) || ' year')::interval)";
|
||||
case "Subtract":
|
||||
if (exp.Arguments[0].Type.FullName == "System.DateTime" || exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault()?.FullName == "System.DateTime")
|
||||
return $"(({left})::timestamp - ({args1})::timestamp)";
|
||||
if (exp.Arguments[0].Type.FullName == "System.TimeSpan" || exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault()?.FullName == "System.TimeSpan")
|
||||
return $"(({left})::timestamp - ({args1})::interval)";
|
||||
break;
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
||||
case "Compare": return $"extract(epoch from ({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::timestamp-({ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)})::timestamp)";
|
||||
case "DaysInMonth": return $"extract(day from ({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} || '-' || {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)} || '-01')::timestamp+'1 month'::interval-'1 day'::interval)";
|
||||
case "Equals": return $"(({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::timestamp = ({ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)})::timestamp)";
|
||||
|
||||
case "IsLeapYear":
|
||||
var isLeapYearArgs1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
return $"(({isLeapYearArgs1})::int8%4=0 AND ({isLeapYearArgs1})::int8%100<>0 OR ({isLeapYearArgs1})::int8%400=0)";
|
||||
|
||||
case "Parse": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::timestamp";
|
||||
case "ParseExact":
|
||||
case "TryParse":
|
||||
case "TryParseExact": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::timestamp";
|
||||
}
|
||||
} else {
|
||||
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
var args1 = exp.Arguments.Count == 0 ? null : ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
switch (exp.Method.Name) {
|
||||
case "Add": return $"(({left})::timestamp+(({args1})||' microseconds')::interval)";
|
||||
case "AddDays": return $"(({left})::timestamp+(({args1})||' day')::interval)";
|
||||
case "AddHours": return $"(({left})::timestamp+(({args1})||' hour')::interval)";
|
||||
case "AddMilliseconds": return $"(({left})::timestamp+(({args1})||' milliseconds')::interval)";
|
||||
case "AddMinutes": return $"(({left})::timestamp+(({args1})||' minute')::interval)";
|
||||
case "AddMonths": return $"(({left})::timestamp+(({args1})||' month')::interval)";
|
||||
case "AddSeconds": return $"(({left})::timestamp+(({args1})||' second')::interval)";
|
||||
case "AddTicks": return $"(({left})::timestamp+(({args1})/10||' microseconds')::interval)";
|
||||
case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)";
|
||||
case "Subtract":
|
||||
if (exp.Arguments[0].Type.FullName == "System.DateTime" || exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault()?.FullName == "System.DateTime")
|
||||
return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)";
|
||||
if (exp.Arguments[0].Type.FullName == "System.TimeSpan" || exp.Arguments[0].Type.GenericTypeArguments.FirstOrDefault()?.FullName == "System.TimeSpan")
|
||||
return $"(({left})::timestamp-(({args1})||' microseconds')::interval)";
|
||||
break;
|
||||
case "Equals": return $"({left} = ({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::timestamp)";
|
||||
case "CompareTo": return $"extract(epoch from ({left})::timestamp-({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::timestamp)";
|
||||
case "ToString": return $"to_char({left}, 'YYYY-MM-DD HH24:MI:SS.US')";
|
||||
}
|
||||
}
|
||||
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
var args1 = ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
switch (exp.Method.Name) {
|
||||
case "Add": return $"(({left})::interval + ({args1})::interval)";
|
||||
case "Subtract": return $"(({left})::interval - ({args1})::interval)";
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
||||
case "Compare": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)}-({ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)}))";
|
||||
case "Equals": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} = {ExpressionLambdaToSql(exp.Arguments[1], _tables, _selectColumnMap, tbtype, isQuoteName)})";
|
||||
case "FromDays": return $"(({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})*{(long)1000000 * 60 * 60 * 24})";
|
||||
case "FromHours": return $"(({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})*{(long)1000000 * 60 * 60})";
|
||||
case "FromMilliseconds": return $"(({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})*1000)";
|
||||
case "FromMinutes": return $"(({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})*{(long)1000000 * 60})";
|
||||
case "FromSeconds": return $"(({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})*1000000)";
|
||||
case "FromTicks": return $"(({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})/10)";
|
||||
case "Parse": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::int8";
|
||||
case "ParseExact":
|
||||
case "TryParse":
|
||||
case "TryParseExact": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::int8";
|
||||
}
|
||||
} else {
|
||||
var left = ExpressionLambdaToSql(exp.Object, _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
var args1 = exp.Arguments.Count == 0 ? null : ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName);
|
||||
switch (exp.Method.Name) {
|
||||
case "Add": return $"({left}+{args1})";
|
||||
case "Subtract": return $"({left}-({args1}))";
|
||||
case "Equals": return $"({left} = {ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})";
|
||||
case "CompareTo": return $"({left}-({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)}))";
|
||||
case "ToString": return $"({left})::varchar";
|
||||
}
|
||||
}
|
||||
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
|
||||
}
|
||||
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, bool isQuoteName) {
|
||||
if (exp.Object == null) {
|
||||
switch (exp.Method.Name) {
|
||||
case "ToBoolean": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} not in ('0','false'))";
|
||||
case "ToByte": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as unsigned)";
|
||||
case "ToChar": return $"substr(cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as char), 1, 1)";
|
||||
case "ToDateTime": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as datetime)";
|
||||
case "ToDecimal": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as decimal(36,18))";
|
||||
case "ToDouble": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as decimal(32,16))";
|
||||
case "ToInt16":
|
||||
case "ToInt32":
|
||||
case "ToInt64":
|
||||
case "ToSByte": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as signed)";
|
||||
case "ToSingle": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as decimal(14,7))";
|
||||
case "ToString": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as char)";
|
||||
case "ToUInt16":
|
||||
case "ToUInt32":
|
||||
case "ToUInt64": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as unsigned)";
|
||||
case "ToBoolean": return $"(({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::varchar not in ('0','false','f','no'))";
|
||||
case "ToByte": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::int2";
|
||||
case "ToChar": return $"substr(({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::char, 1, 1)";
|
||||
case "ToDateTime": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::timestamp";
|
||||
case "ToDecimal": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::numeric";
|
||||
case "ToDouble": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::float8";
|
||||
case "ToInt16": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::int2";
|
||||
case "ToInt32": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::int4";
|
||||
case "ToInt64": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::int8";
|
||||
case "ToSByte": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::int2";
|
||||
case "ToSingle": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::float4";
|
||||
case "ToString": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::varchar";
|
||||
case "ToUInt16": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::int2";
|
||||
case "ToUInt32": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::int4";
|
||||
case "ToUInt64": return $"({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)})::int8";
|
||||
}
|
||||
}
|
||||
throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析");
|
||||
|
@ -16,6 +16,7 @@ namespace FreeSql.PostgreSQL {
|
||||
|
||||
internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, object value) {
|
||||
if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
|
||||
else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower();
|
||||
NpgsqlParameter ret = null;
|
||||
if (value == null) ret = new NpgsqlParameter { ParameterName = $"{parameterName}", Value = DBNull.Value };
|
||||
else {
|
||||
@ -52,7 +53,7 @@ namespace FreeSql.PostgreSQL {
|
||||
|
||||
internal override string FormatSql(string sql, params object[] args) => sql?.FormatPostgreSQL(args);
|
||||
internal override string QuoteSqlName(string name) => $"\"{name.Trim('"').Replace(".", "\".\"")}\"";
|
||||
internal override string QuoteParamterName(string name) => $"@{name}";
|
||||
internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
|
||||
internal override string IsNull(string sql, object value) => $"coalesce({sql}, {value})";
|
||||
internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"{left} || {right}";
|
||||
}
|
||||
|
@ -22,50 +22,51 @@ namespace FreeSql.SqlServer {
|
||||
}
|
||||
|
||||
public bool IsAutoSyncStructure { get; set; } = true;
|
||||
public bool IsSyncStructureToLower { get; set; } = false;
|
||||
|
||||
static object _dicCsToDbLock = new object();
|
||||
static Dictionary<string, (SqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable)> _dicCsToDb = new Dictionary<string, (SqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable)>() {
|
||||
{ typeof(bool).FullName, (SqlDbType.Bit, "bit","bit NOT NULL", null, false) },{ typeof(bool?).FullName, (SqlDbType.Bit, "bit","bit", null, true) },
|
||||
static Dictionary<string, (SqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (SqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
|
||||
{ typeof(bool).FullName, (SqlDbType.Bit, "bit","bit NOT NULL", null, false, false) },{ typeof(bool?).FullName, (SqlDbType.Bit, "bit","bit", null, true, null) },
|
||||
|
||||
{ typeof(sbyte).FullName, (SqlDbType.TinyInt, "tinyint", "tinyint NOT NULL", false, false) },{ typeof(sbyte?).FullName, (SqlDbType.TinyInt, "tinyint", "tinyint", false, true) },
|
||||
{ typeof(short).FullName, (SqlDbType.SmallInt, "smallint","smallint NOT NULL", false, false) },{ typeof(short?).FullName, (SqlDbType.SmallInt, "smallint", "smallint", false, true) },
|
||||
{ typeof(int).FullName, (SqlDbType.Int, "int", "int NOT NULL", false, false) },{ typeof(int?).FullName, (SqlDbType.Int, "int", "int", false, true) },
|
||||
{ typeof(long).FullName, (SqlDbType.BigInt, "bigint","bigint NOT NULL", false, false) },{ typeof(long?).FullName, (SqlDbType.BigInt, "bigint","bigint", false, true) },
|
||||
{ typeof(sbyte).FullName, (SqlDbType.TinyInt, "tinyint", "tinyint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, (SqlDbType.TinyInt, "tinyint", "tinyint", false, true, null) },
|
||||
{ typeof(short).FullName, (SqlDbType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, (SqlDbType.SmallInt, "smallint", "smallint", false, true, null) },
|
||||
{ typeof(int).FullName, (SqlDbType.Int, "int", "int NOT NULL", false, false, 0) },{ typeof(int?).FullName, (SqlDbType.Int, "int", "int", false, true, null) },
|
||||
{ typeof(long).FullName, (SqlDbType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, (SqlDbType.BigInt, "bigint","bigint", false, true, null) },
|
||||
|
||||
{ typeof(byte).FullName, (SqlDbType.TinyInt, "tinyint","tinyint NOT NULL", true, false) },{ typeof(byte?).FullName, (SqlDbType.TinyInt, "tinyint","tinyint", true, true) },
|
||||
{ typeof(ushort).FullName, (SqlDbType.SmallInt, "smallint","smallint NOT NULL", true, false) },{ typeof(ushort?).FullName, (SqlDbType.SmallInt, "smallint", "smallint", true, true) },
|
||||
{ typeof(uint).FullName, (SqlDbType.Int, "int", "int NOT NULL", true, false) },{ typeof(uint?).FullName, (SqlDbType.Int, "int", "int", true, true) },
|
||||
{ typeof(ulong).FullName, (SqlDbType.BigInt, "bigint", "bigint NOT NULL", true, false) },{ typeof(ulong?).FullName, (SqlDbType.BigInt, "bigint", "bigint", true, true) },
|
||||
{ typeof(byte).FullName, (SqlDbType.TinyInt, "tinyint","tinyint NOT NULL", true, false, 0) },{ typeof(byte?).FullName, (SqlDbType.TinyInt, "tinyint","tinyint", true, true, null) },
|
||||
{ typeof(ushort).FullName, (SqlDbType.SmallInt, "smallint","smallint NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, (SqlDbType.SmallInt, "smallint", "smallint", true, true, null) },
|
||||
{ typeof(uint).FullName, (SqlDbType.Int, "int", "int NOT NULL", true, false, 0) },{ typeof(uint?).FullName, (SqlDbType.Int, "int", "int", true, true, null) },
|
||||
{ typeof(ulong).FullName, (SqlDbType.BigInt, "bigint", "bigint NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, (SqlDbType.BigInt, "bigint", "bigint", true, true, null) },
|
||||
|
||||
{ typeof(double).FullName, (SqlDbType.Float, "float", "float NOT NULL", false, false) },{ typeof(double?).FullName, (SqlDbType.Float, "float", "float", false, true) },
|
||||
{ typeof(float).FullName, (SqlDbType.Real, "real","real NOT NULL", false, false) },{ typeof(float?).FullName, (SqlDbType.Real, "real","real", false, true) },
|
||||
{ typeof(decimal).FullName, (SqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false) },{ typeof(decimal?).FullName, (SqlDbType.Decimal, "decimal", "decimal(10,2)", false, true) },
|
||||
{ typeof(double).FullName, (SqlDbType.Float, "float", "float NOT NULL", false, false, 0) },{ typeof(double?).FullName, (SqlDbType.Float, "float", "float", false, true, null) },
|
||||
{ typeof(float).FullName, (SqlDbType.Real, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, (SqlDbType.Real, "real","real", false, true, null) },
|
||||
{ typeof(decimal).FullName, (SqlDbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, (SqlDbType.Decimal, "decimal", "decimal(10,2)", false, true, null) },
|
||||
|
||||
{ typeof(TimeSpan).FullName, (SqlDbType.Time, "time","time NOT NULL", false, false) },{ typeof(TimeSpan?).FullName, (SqlDbType.Time, "time", "time",false, true) },
|
||||
{ typeof(DateTime).FullName, (SqlDbType.DateTime, "datetime", "datetime NOT NULL", false, false) },{ typeof(DateTime?).FullName, (SqlDbType.DateTime, "datetime", "datetime", false, true) },
|
||||
{ typeof(DateTimeOffset).FullName, (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset NOT NULL", false, false) },{ typeof(DateTimeOffset?).FullName, (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset", false, true) },
|
||||
{ typeof(TimeSpan).FullName, (SqlDbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, (SqlDbType.Time, "time", "time",false, true, null) },
|
||||
{ typeof(DateTime).FullName, (SqlDbType.DateTime, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, (SqlDbType.DateTime, "datetime", "datetime", false, true, null) },
|
||||
{ typeof(DateTimeOffset).FullName, (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset NOT NULL", false, false, new DateTimeOffset(new DateTime(1970,1,1), TimeSpan.Zero)) },{ typeof(DateTimeOffset?).FullName, (SqlDbType.DateTimeOffset, "datetimeoffset", "datetimeoffset", false, true, null) },
|
||||
|
||||
{ typeof(byte[]).FullName, (SqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null) },
|
||||
{ typeof(string).FullName, (SqlDbType.NVarChar, "nvarchar", "nvarchar(255)", false, null) },
|
||||
{ typeof(byte[]).FullName, (SqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) },
|
||||
{ typeof(string).FullName, (SqlDbType.NVarChar, "nvarchar", "nvarchar(255)", false, null, "") },
|
||||
|
||||
{ typeof(Guid).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false) },{ typeof(Guid?).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true) },
|
||||
{ typeof(Guid).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, (SqlDbType.UniqueIdentifier, "uniqueidentifier", "uniqueidentifier", false, true, null) },
|
||||
};
|
||||
|
||||
public (int type, string dbtype, string dbtypeFull, bool? isnullable)? GetDbInfo(Type type) {
|
||||
if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new (int, string, string, bool?)?(((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable));
|
||||
public (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));
|
||||
var enumType = type.IsEnum ? type : null;
|
||||
if (enumType == null && type.FullName.StartsWith("System.Nullable`1[") && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First();
|
||||
if (enumType != null) {
|
||||
var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ?
|
||||
(SqlDbType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true) :
|
||||
(SqlDbType.Int, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true);
|
||||
(SqlDbType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, Enum.GetValues(enumType).GetValue(0)) :
|
||||
(SqlDbType.Int, "int", $"int{(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);
|
||||
return ((int)newItem.Item1, newItem.Item2, newItem.Item3, newItem.Item5, newItem.Item6);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -186,9 +187,10 @@ use " + database, tboldname ?? tbname);
|
||||
//添加列
|
||||
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType);
|
||||
if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)");
|
||||
var addcoldbdefault = tb.Properties[tbcol.CsName].GetValue(Activator.CreateInstance(tb.Type));
|
||||
if (tbcol.Attribute.IsNullable == false) addcoldbdefault = tbcol.Attribute.DbDefautValue;
|
||||
if (addcoldbdefault != null) sbalter.Append(_commonUtils.FormatSql(" default({0})", addcoldbdefault));
|
||||
if (tbcol.Attribute.IsNullable == false) {
|
||||
var addcoldbdefault = tbcol.Attribute.DbDefautValue;
|
||||
if (addcoldbdefault != null) sbalter.Append(_commonUtils.FormatSql(" default({0})", addcoldbdefault));
|
||||
}
|
||||
sbalter.Append(";\r\n");
|
||||
}
|
||||
}
|
||||
@ -225,26 +227,21 @@ use " + database, tboldname ?? tbname);
|
||||
if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n");
|
||||
sb.Append("IF EXISTS(SELECT 1 FROM ").Append(tablename).Append(")\r\n");
|
||||
sb.Append("\tEXEC('INSERT INTO ").Append(tmptablename).Append(" (");
|
||||
foreach (var tbcol in tb.Columns.Values) {
|
||||
if (tbstruct.ContainsKey(tbcol.Attribute.Name) ||
|
||||
string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.ContainsKey(tbcol.Attribute.OldName)) { //导入旧表存在的字段
|
||||
sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
|
||||
}
|
||||
}
|
||||
foreach (var tbcol in tb.Columns.Values)
|
||||
sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
|
||||
sb.Remove(sb.Length - 2, 2).Append(")\r\n\t\tSELECT ");
|
||||
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)) {
|
||||
var insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column);
|
||||
if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) {
|
||||
var tbcoldbtype = tbcol.Attribute.DbType.Split(' ').First();
|
||||
insertvalue = $"cast({insertvalue} as {tbcoldbtype})";
|
||||
}
|
||||
if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) {
|
||||
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 = $"isnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")})";
|
||||
}
|
||||
sb.Append(insertvalue).Append(", ");
|
||||
}
|
||||
} else if (tbcol.Attribute.IsNullable == false)
|
||||
insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''");
|
||||
sb.Append(insertvalue).Append(", ");
|
||||
}
|
||||
sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(" WITH (HOLDLOCK TABLOCKX)');\r\n");
|
||||
if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" OFF;\r\n");
|
||||
|
@ -15,6 +15,7 @@ namespace FreeSql.SqlServer {
|
||||
|
||||
internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, object value) {
|
||||
if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
|
||||
else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower();
|
||||
SqlParameter ret = null;
|
||||
if (value == null) ret = new SqlParameter { ParameterName = $"{parameterName}", Value = DBNull.Value };
|
||||
else {
|
||||
@ -43,7 +44,7 @@ namespace FreeSql.SqlServer {
|
||||
|
||||
internal override string FormatSql(string sql, params object[] args) => sql?.FormatSqlServer(args);
|
||||
internal override string QuoteSqlName(string name) => $"[{name.TrimStart('[').TrimEnd(']').Replace(".", "].[")}]";
|
||||
internal override string QuoteParamterName(string name) => $"@{name}";
|
||||
internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
|
||||
internal override string IsNull(string sql, object value) => $"isnull({sql}, {value})";
|
||||
internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"{(leftType.FullName == "System.String" ? left : $"cast({left} as nvarchar)")} + {(rightType.FullName == "System.String" ? right : $"cast({right} as nvarchar)")}";
|
||||
}
|
||||
|
Reference in New Issue
Block a user