From 54b5528cb496c3a813904f51635e354d9c9768c8 Mon Sep 17 00:00:00 2001 From: sunkaixuan <610262374@qq.com> Date: Tue, 25 Jul 2017 22:33:58 +0800 Subject: [PATCH 1/3] MySqlGuid --- .../Abstract/DbBindProvider/IDataReaderEntityBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/Asp.Net/SqlSugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs b/Src/Asp.Net/SqlSugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs index cbc10f259..d390000cd 100644 --- a/Src/Asp.Net/SqlSugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs +++ b/Src/Asp.Net/SqlSugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs @@ -236,7 +236,7 @@ namespace SqlSugar method = getString; if (bindProperyTypeName == "guid") { - method = getConvertStringGuid; + method =isNullableType? getConvertStringGuid : getStringGuid; } break; case CSharpDataType.DateTime: From 728d6158cff3a89469970226b68864d2fee98a5b Mon Sep 17 00:00:00 2001 From: sunkaixuan <610262374@qq.com> Date: Tue, 25 Jul 2017 23:32:28 +0800 Subject: [PATCH 2/3] Add Oracle --- .../Oracle/CodeFirst/OracleCodeFirst.cs | 11 + .../Realization/Oracle/DbBind/OracleDbBind.cs | 47 ++++ .../Oracle/DbFirst/OracleDbFirst.cs | 11 + .../DbMaintenance/OracleDbMaintenance.cs | 205 ++++++++++++++++++ .../Realization/Oracle/OracleProvider.cs | 103 +++++++++ .../Oracle/Queryable/OracleQueryable.cs | 45 ++++ .../Oracle/SqlBuilder/OracleBuilder.cs | 51 +++++ .../Oracle/SqlBuilder/OracleDeleteBuilder.cs | 13 ++ .../SqlBuilder/OracleExpressionContext.cs | 25 +++ .../Oracle/SqlBuilder/OracleInsertBuilder.cs | 12 + .../Oracle/SqlBuilder/OracleQueryBuilder.cs | 19 ++ .../Oracle/SqlBuilder/OracleUpdateBuilder.cs | 12 + .../References/Oracle.ManagedDataAccess.dll | Bin 0 -> 6530560 bytes Src/Asp.Net/SqlSugar/SqlSugar.csproj | 19 +- 14 files changed, 572 insertions(+), 1 deletion(-) create mode 100644 Src/Asp.Net/SqlSugar/Realization/Oracle/CodeFirst/OracleCodeFirst.cs create mode 100644 Src/Asp.Net/SqlSugar/Realization/Oracle/DbBind/OracleDbBind.cs create mode 100644 Src/Asp.Net/SqlSugar/Realization/Oracle/DbFirst/OracleDbFirst.cs create mode 100644 Src/Asp.Net/SqlSugar/Realization/Oracle/DbMaintenance/OracleDbMaintenance.cs create mode 100644 Src/Asp.Net/SqlSugar/Realization/Oracle/OracleProvider.cs create mode 100644 Src/Asp.Net/SqlSugar/Realization/Oracle/Queryable/OracleQueryable.cs create mode 100644 Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleBuilder.cs create mode 100644 Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleDeleteBuilder.cs create mode 100644 Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleExpressionContext.cs create mode 100644 Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleInsertBuilder.cs create mode 100644 Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleQueryBuilder.cs create mode 100644 Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleUpdateBuilder.cs create mode 100644 Src/Asp.Net/SqlSugar/References/Oracle.ManagedDataAccess.dll diff --git a/Src/Asp.Net/SqlSugar/Realization/Oracle/CodeFirst/OracleCodeFirst.cs b/Src/Asp.Net/SqlSugar/Realization/Oracle/CodeFirst/OracleCodeFirst.cs new file mode 100644 index 000000000..d54c937a5 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Realization/Oracle/CodeFirst/OracleCodeFirst.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SqlSugar +{ + public class OracleCodeFirst : CodeFirstProvider + { + } +} diff --git a/Src/Asp.Net/SqlSugar/Realization/Oracle/DbBind/OracleDbBind.cs b/Src/Asp.Net/SqlSugar/Realization/Oracle/DbBind/OracleDbBind.cs new file mode 100644 index 000000000..15a7e1609 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Realization/Oracle/DbBind/OracleDbBind.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +namespace SqlSugar +{ + public class OracleDbBind : DbBindProvider + { + public override List> MappingTypes + { + get + { + return new List>() + { + new KeyValuePair("int",CSharpDataType.@int), + new KeyValuePair("varchar",CSharpDataType.@string), + new KeyValuePair("nvarchar",CSharpDataType.@string), + new KeyValuePair("sql_variant",CSharpDataType.@string), + new KeyValuePair("text",CSharpDataType.@string), + new KeyValuePair("char",CSharpDataType.@string), + new KeyValuePair("ntext",CSharpDataType.@string), + new KeyValuePair("nchar",CSharpDataType.@string), + new KeyValuePair("bigint",CSharpDataType.@long), + new KeyValuePair("bit",CSharpDataType.@bool), + new KeyValuePair("datetime",CSharpDataType.DateTime), + new KeyValuePair("time",CSharpDataType.DateTime), + new KeyValuePair("smalldatetime",CSharpDataType.DateTime), + new KeyValuePair("timestamp",CSharpDataType.DateTime), + new KeyValuePair("datetime2",CSharpDataType.DateTime), + new KeyValuePair("date",CSharpDataType.DateTime), + new KeyValuePair("decimal",CSharpDataType.@decimal), + new KeyValuePair("single",CSharpDataType.@decimal), + new KeyValuePair("money",CSharpDataType.@decimal), + new KeyValuePair("numeric",CSharpDataType.@decimal), + new KeyValuePair("smallmoney",CSharpDataType.@decimal), + new KeyValuePair("float",CSharpDataType.@double), + new KeyValuePair("real",CSharpDataType.@float), + new KeyValuePair("smallint",CSharpDataType.@short), + new KeyValuePair("tinyint",CSharpDataType.@byte), + new KeyValuePair("uniqueidentifier",CSharpDataType.Guid), + new KeyValuePair("binary",CSharpDataType.byteArray), + new KeyValuePair("image",CSharpDataType.byteArray), + new KeyValuePair("varbinary",CSharpDataType.byteArray)}; + } + } + } +} diff --git a/Src/Asp.Net/SqlSugar/Realization/Oracle/DbFirst/OracleDbFirst.cs b/Src/Asp.Net/SqlSugar/Realization/Oracle/DbFirst/OracleDbFirst.cs new file mode 100644 index 000000000..f58fefb4e --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Realization/Oracle/DbFirst/OracleDbFirst.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SqlSugar +{ + public class OracleDbFirst : DbFirstProvider + { + } +} diff --git a/Src/Asp.Net/SqlSugar/Realization/Oracle/DbMaintenance/OracleDbMaintenance.cs b/Src/Asp.Net/SqlSugar/Realization/Oracle/DbMaintenance/OracleDbMaintenance.cs new file mode 100644 index 000000000..a8fbf80f9 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Realization/Oracle/DbMaintenance/OracleDbMaintenance.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SqlSugar +{ + public class OracleDbMaintenance : DbMaintenanceProvider + { + #region DML + protected override string GetColumnInfosByTableNameSql + { + get + { + string sql = @"SELECT Sysobjects.name AS TableName, + syscolumns.Id AS TableId, + syscolumns.name AS DbColumnName, + systypes.name AS DataType, + syscolumns.length AS [Length], + sys.extended_properties.[value] AS [ColumnDescription], + syscomments.text AS DefaultValue, + syscolumns.isnullable AS IsNullable, + columnproperty(syscolumns.id,syscolumns.name,'IsIdentity')as IsIdentity, + (CASE + WHEN EXISTS + ( + select 1 + from sysindexes i + join sysindexkeys k on i.id = k.id and i.indid = k.indid + join sysobjects o on i.id = o.id + join syscolumns c on i.id=c.id and k.colid = c.colid + where o.xtype = 'U' + and exists(select 1 from sysobjects where xtype = 'PK' and name = i.name) + and o.name=sysobjects.name and c.name=syscolumns.name + ) THEN 1 + ELSE 0 + END) AS IsPrimaryKey + FROM syscolumns + INNER JOIN systypes ON syscolumns.xtype = systypes.xtype + LEFT JOIN sysobjects ON syscolumns.id = sysobjects.id + LEFT OUTER JOIN sys.extended_properties ON (sys.extended_properties.minor_id = syscolumns.colid + AND sys.extended_properties.major_id = syscolumns.id) + LEFT OUTER JOIN syscomments ON syscolumns.cdefault = syscomments.id + WHERE syscolumns.id IN + (SELECT id + FROM sysobjects + WHERE xtype IN('u', + 'v') ) + AND (systypes.name <> 'sysname') + AND sysobjects.name='{0}' + AND systypes.name<>'geometry' + AND systypes.name<>'geography' + ORDER BY syscolumns.colid"; + return sql; + } + } + protected override string GetTableInfoListSql + { + get + { + return @"SELECT s.Name,Convert(varchar(max),tbp.value) as Description + FROM sysobjects s + LEFT JOIN sys.extended_properties as tbp ON s.id=tbp.major_id and tbp.minor_id=0 WHERE s.xtype IN('U') AND (tbp.Name='MS_Description' OR tbp.Name is null)"; + } + } + protected override string GetViewInfoListSql + { + get + { + return @"SELECT s.Name,Convert(varchar(max),tbp.value) as Description + FROM sysobjects s + LEFT JOIN sys.extended_properties as tbp ON s.id=tbp.major_id and tbp.minor_id=0 WHERE s.xtype IN('V') AND (tbp.Name='MS_Description' OR tbp.Name is null)"; + } + } + #endregion + + #region DDL + protected override string AddPrimaryKeySql + { + get + { + return "ALTER TABLE {0} ADD CONSTRAINT {1} PRIMARY KEY({2})"; + } + } + protected override string AddColumnToTableSql + { + get + { + return "ALTER TABLE {0} ADD {1} {2}{3} {4} {5} {6}"; + } + } + protected override string AlterColumnToTableSql + { + get + { + return "ALTER TABLE {0} ALTER COLUMN {1} {2}{3} {4} {5} {6}"; + } + } + protected override string BackupDataBaseSql + { + get + { + return @"USE master;BACKUP DATABASE {0} TO disk = '{1}'"; + } + } + protected override string CreateTableSql + { + get + { + return "CREATE TABLE {0}(\r\n{1})"; + } + } + protected override string CreateTableColumn + { + get + { + return "{0} {1}{2} {3} {4} {5}"; + } + } + protected override string TruncateTableSql + { + get + { + return "TRUNCATE TABLE {0}"; + } + } + protected override string BackupTableSql + { + get + { + return "SELECT TOP {0} * INTO {1} FROM {2}"; + } + } + protected override string DropTableSql + { + get + { + return "DROP TABLE {0}"; + } + } + protected override string DropColumnToTableSql + { + get + { + return "ALTER TABLE {0} DROP COLUMN {1}"; + } + } + protected override string DropConstraintSql + { + get + { + return "ALTER TABLE {0} DROP CONSTRAINT {1}"; + } + } + protected override string RenameColumnSql + { + get + { + return "exec sp_rename '{0}.{1}','{2}','column';"; + } + } + #endregion + + #region Check + protected override string CheckSystemTablePermissionsSql + { + get + { + return "select top 1 id from sysobjects"; + } + } + #endregion + + #region Scattered + protected override string CreateTableNull + { + get + { + return "NULL"; + } + } + protected override string CreateTableNotNull + { + get + { + return "NOT NULL"; + } + } + protected override string CreateTablePirmaryKey + { + get + { + return "PRIMARY KEY"; + } + } + protected override string CreateTableIdentity + { + get + { + return "IDENTITY(1,1)"; + } + } + #endregion + } +} diff --git a/Src/Asp.Net/SqlSugar/Realization/Oracle/OracleProvider.cs b/Src/Asp.Net/SqlSugar/Realization/Oracle/OracleProvider.cs new file mode 100644 index 000000000..a00f3528f --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Realization/Oracle/OracleProvider.cs @@ -0,0 +1,103 @@ +using Oracle.ManagedDataAccess.Client; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +namespace SqlSugar +{ + public class OracleProvider : AdoProvider + { + public OracleProvider() { } + public override IDbConnection Connection + { + get + { + if (base._DbConnection == null) + { + base._DbConnection = new OracleConnection(base.Context.CurrentConnectionConfig.ConnectionString); + } + return base._DbConnection; + } + set + { + base._DbConnection = value; + } + } + /// + /// Only SqlServer + /// + /// + public override void BeginTran(string transactionName) + { + ((OracleConnection)this.Connection).BeginTransaction(); + } + /// + /// Only SqlServer + /// + /// + /// + public override void BeginTran(IsolationLevel iso, string transactionName) + { + ((OracleConnection)this.Connection).BeginTransaction(iso); + } + public override IDataAdapter GetAdapter() + { + return new SqlDataAdapter(); + } + public override IDbCommand GetCommand(string sql, SugarParameter[] parameters) + { + OracleCommand sqlCommand = new OracleCommand(sql, (OracleConnection)this.Connection); + sqlCommand.CommandType = this.CommandType; + sqlCommand.CommandTimeout = this.CommandTimeOut; + if (this.Transaction != null) + { + sqlCommand.Transaction = (OracleTransaction)this.Transaction; + } + if (parameters.IsValuable()) + { + IDataParameter[] ipars = ToIDbDataParameter(parameters); + sqlCommand.Parameters.AddRange((OracleParameter[])ipars); + } + CheckConnection(); + return sqlCommand; + } + public override void SetCommandToAdapter(IDataAdapter dataAdapter, IDbCommand command) + { + ((OracleDataAdapter)dataAdapter).SelectCommand = (OracleCommand)command; + } + /// + /// if mysql return MySqlParameter[] pars + /// if sqlerver return SqlParameter[] pars ... + /// + /// + /// + public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters) + { + if (parameters == null || parameters.Length == 0) return null; + OracleParameter[] result = new OracleParameter[parameters.Length]; + int index = 0; + foreach (var parameter in parameters) + { + if (parameter.Value == null) parameter.Value = DBNull.Value; + var sqlParameter = new OracleParameter(); + sqlParameter.ParameterName = parameter.ParameterName; + sqlParameter.UdtTypeName = parameter.UdtTypeName; + sqlParameter.Size = parameter.Size; + sqlParameter.Value = parameter.Value; + sqlParameter.DbType = parameter.DbType; + sqlParameter.Direction = parameter.Direction; + result[index] = sqlParameter; + if (sqlParameter.Direction == ParameterDirection.Output) { + if (this.OutputParameters == null) this.OutputParameters = new List(); + this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName); + this.OutputParameters.Add(sqlParameter); + } + ++index; + } + return result; + } + } +} diff --git a/Src/Asp.Net/SqlSugar/Realization/Oracle/Queryable/OracleQueryable.cs b/Src/Asp.Net/SqlSugar/Realization/Oracle/Queryable/OracleQueryable.cs new file mode 100644 index 000000000..ef832c8f8 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Realization/Oracle/Queryable/OracleQueryable.cs @@ -0,0 +1,45 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class OracleQueryable : QueryableProvider + { + public override ISugarQueryable With(string withString) + { + return this; + } + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } + public class OracleQueryable : QueryableProvider + { + + } +} diff --git a/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleBuilder.cs b/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleBuilder.cs new file mode 100644 index 000000000..2c497ca5b --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleBuilder.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public class OracleBuilder : SqlBuilderProvider + { + public override string GetTranslationTableName(string name) + { + Check.ArgumentNullException(name, string.Format(ErrorMessage.ObjNotExist, "Table Name")); + var context = this.Context; + var mappingInfo = context + .MappingTables + .FirstOrDefault(it => it.EntityName.Equals(name, StringComparison.CurrentCultureIgnoreCase)); + name = (mappingInfo == null ? name : mappingInfo.DbTableName); + if (name.Contains("[")) + return name; + else + return "[" + name + "]"; + } + public override string GetTranslationColumnName(string entityName, string propertyName) + { + Check.ArgumentNullException(entityName, string.Format(ErrorMessage.ObjNotExist, "Table Name")); + Check.ArgumentNullException(propertyName, string.Format(ErrorMessage.ObjNotExist, "Column Name")); + var context = this.Context; + var mappingInfo = context + .MappingColumns + .FirstOrDefault(it => + it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase) && + it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + return (mappingInfo == null ? "[" + propertyName + "]" : "[" + mappingInfo.DbColumnName + "]"); + } + + public override string GetTranslationColumnName(string propertyName) + { + if (propertyName.Contains("[")) return propertyName; + else + return "[" + propertyName + "]"; + } + + public override string GetNoTranslationColumnName(string name) + { + if (!name.Contains("[")) return name; + return name == null ? string.Empty : Regex.Match(name, @".*\[(.*?)\]").Groups[1].Value; + } + } +} diff --git a/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleDeleteBuilder.cs b/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleDeleteBuilder.cs new file mode 100644 index 000000000..504d0befa --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleDeleteBuilder.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public class OracleDeleteBuilder : DeleteBuilder + { + + } +} diff --git a/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleExpressionContext.cs b/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleExpressionContext.cs new file mode 100644 index 000000000..1744f67f4 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleExpressionContext.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public partial class OracleExpressionContext : ExpressionContext, ILambdaExpressions + { + public SqlSugarClient Context { get; set; } + public OracleExpressionContext() + { + base.DbMehtods = new SqlServerMethod(); + } + + } + public partial class SqlServerMethod : DefaultDbMethod, IDbMethods + { + + } +} diff --git a/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleInsertBuilder.cs b/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleInsertBuilder.cs new file mode 100644 index 000000000..36e75d746 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleInsertBuilder.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public class OracleInsertBuilder : InsertBuilder + { + } +} diff --git a/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleQueryBuilder.cs b/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleQueryBuilder.cs new file mode 100644 index 000000000..dc4726cf4 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleQueryBuilder.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public class OracleQueryBuilder : QueryBuilder + { + public override string SqlTemplate + { + get + { + return "SELECT {0}{{$:OrderByString:$}} FROM {1}{2}{3}{4}"; + } + } + } +} diff --git a/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleUpdateBuilder.cs b/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleUpdateBuilder.cs new file mode 100644 index 000000000..3e16302fd --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Realization/Oracle/SqlBuilder/OracleUpdateBuilder.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public class OracleUpdateBuilder : UpdateBuilder + { + } +} diff --git a/Src/Asp.Net/SqlSugar/References/Oracle.ManagedDataAccess.dll b/Src/Asp.Net/SqlSugar/References/Oracle.ManagedDataAccess.dll new file mode 100644 index 0000000000000000000000000000000000000000..473ca83dad355f5ff50eb413cb3ef145ac3949c6 GIT binary patch literal 6530560 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