From 25b98f2fe96549a37e291d10420431042f6e4a79 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 23 Aug 2022 01:28:47 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Provider.Oracl?= =?UTF-8?q?eOledb=20=E8=A7=A3=E5=86=B3US7ASCII=20=E4=B8=AD=E6=96=87?= =?UTF-8?q?=E4=B9=B1=E7=A0=81=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql-lite.sln | 19 +- FreeSql/FreeSql.xml | 5 + FreeSql/FreeSqlBuilder.cs | 1 + .../FreeSql.Provider.Custom/OracleAdapter.cs | 173 ++++++++++++++++++ .../Curd/OracleInsert.cs | 8 +- .../OracleAdo/OracleAdo.cs | 9 +- .../OracleAdo/OracleConnectionPool.cs | 13 +- .../OracleCodeFirst.cs | 86 ++++++--- .../FreeSql.Provider.Oracle/OracleDbFirst.cs | 97 ++++++++++ .../OracleExtensions.cs | 7 + .../FreeSql.Provider.OracleOledb.csproj | 52 ++++++ .../OracleOledbUtils.cs | 156 ++++++++++++++++ .../FreeSql.Provider.OracleOledb/key.snk | Bin 0 -> 596 bytes 13 files changed, 590 insertions(+), 36 deletions(-) create mode 100644 Providers/FreeSql.Provider.Custom/OracleAdapter.cs create mode 100644 Providers/FreeSql.Provider.OracleOledb/FreeSql.Provider.OracleOledb.csproj create mode 100644 Providers/FreeSql.Provider.OracleOledb/OracleOledbUtils.cs create mode 100644 Providers/FreeSql.Provider.OracleOledb/key.snk diff --git a/FreeSql-lite.sln b/FreeSql-lite.sln index ecb21b67..eefc4343 100644 --- a/FreeSql-lite.sln +++ b/FreeSql-lite.sln @@ -77,6 +77,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.SqliteCore EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "base_entity", "Examples\base_entity\base_entity.csproj", "{9D82A683-2950-4E8A-B078-A422ECA6AAA5}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.OracleOledb", "Providers\FreeSql.Provider.OracleOledb\FreeSql.Provider.OracleOledb.csproj", "{19D2E22A-B000-46B6-AFC8-60BF01A51C9A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -411,6 +413,18 @@ Global {9D82A683-2950-4E8A-B078-A422ECA6AAA5}.Release|x64.Build.0 = Release|Any CPU {9D82A683-2950-4E8A-B078-A422ECA6AAA5}.Release|x86.ActiveCfg = Release|Any CPU {9D82A683-2950-4E8A-B078-A422ECA6AAA5}.Release|x86.Build.0 = Release|Any CPU + {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Debug|x64.ActiveCfg = Debug|Any CPU + {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Debug|x64.Build.0 = Debug|Any CPU + {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Debug|x86.ActiveCfg = Debug|Any CPU + {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Debug|x86.Build.0 = Debug|Any CPU + {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Release|Any CPU.Build.0 = Release|Any CPU + {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Release|x64.ActiveCfg = Release|Any CPU + {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Release|x64.Build.0 = Release|Any CPU + {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Release|x86.ActiveCfg = Release|Any CPU + {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -439,10 +453,11 @@ Global {BDE8EDC6-2646-45E0-A921-39CD1538A8C5} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {D4FEE5C1-6805-4B46-B10B-BE5CC942B883} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {9D82A683-2950-4E8A-B078-A422ECA6AAA5} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} + {19D2E22A-B000-46B6-AFC8-60BF01A51C9A} = {2A381C57-2697-427B-9F10-55DA11FD02E4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {089687FA-5D21-40AC-BA8A-AA0D1E1H7F98} - RESX_PrefixTranslations = True RESX_NeutralResourcesLanguage = en-US + RESX_PrefixTranslations = True + SolutionGuid = {089687FA-5D21-40AC-BA8A-AA0D1E1H7F98} EndGlobalSection EndGlobal diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 91120bfb..debb531e 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -713,6 +713,11 @@ 天津南大通用数据技术股份有限公司成立于2004年,是国产数据库、大数据领域的知名企业,基于 Odbc 的实现 + + + 基于 OleDb 实现访问 Oracle 数据库,解决 US7ASCII 中文乱码问题 https://blog.csdn.net/guhun_shmily/article/details/83064225 + + 获取 IDbConnection 对应的 IFreeSql 实例 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index df8f3bc7..77c9363b 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -229,6 +229,7 @@ namespace FreeSql break; case DataType.Oracle: type = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(typeof(TMark)); + if (type == null) type = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.OracleOledb")?.MakeGenericType(typeof(TMark)); //基于 oledb 实现,解决 US7ASCII 中文乱码问题 if (type == null) throwNotFind("FreeSql.Provider.Oracle.dll", "FreeSql.Oracle.OracleProvider<>"); break; case DataType.Sqlite: diff --git a/Providers/FreeSql.Provider.Custom/OracleAdapter.cs b/Providers/FreeSql.Provider.Custom/OracleAdapter.cs new file mode 100644 index 00000000..9d52af36 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/OracleAdapter.cs @@ -0,0 +1,173 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSql.Custom +{ + public class OracleAdapter + { + /// + /// Select TOP 1,或 Limit 1 风格 + /// + public virtual SelecTopStyle SelectTopStyle => SelecTopStyle.RowNum; + public enum SelecTopStyle { Top, Limit, RowNum } + + /// + /// 插入成功后,获取自增值 + /// + public virtual string InsertAfterGetIdentitySql => "SELECT SCOPE_IDENTITY()"; + /// + /// 批量插入时,自动拆分的每次执行数量 + /// + public virtual int InsertBatchSplitLimit => 255; + /// + /// 批量更新时,自动拆分的每次执行数量 + /// + public virtual int UpdateBatchSplitLimit => 255; + + public virtual string MappingDbTypeBit => "int"; + public virtual string MappingDbTypeSmallInt => "smallint"; + public virtual string MappingDbTypeInt => "int"; + public virtual string MappingDbTypeBigInt => "bigint"; + public virtual string MappingDbTypeTinyInt => "tinyint"; + public virtual string MappingDbTypeDecimal => "decimal"; + public virtual string MappingDbTypeDouble => "float"; + public virtual string MappingDbTypeReal => "real"; + public virtual string MappingDbTypeDateTime => "datetime"; + public virtual string MappingDbTypeVarBinary => "varbinary"; + public virtual string MappingDbTypeVarChar => "nvarchar"; + public virtual string MappingDbTypeChar => "char"; + public virtual string MappingDbTypeText => "nvarchar(max)"; + public virtual string MappingDbTypeUniqueIdentifier => "uniqueidentifier"; + + public virtual char QuoteSqlNameLeft => '['; + public virtual char QuoteSqlNameRight => ']'; + + public virtual string FieldSql(Type type, string columnName) => columnName; + public virtual string UnicodeStringRawSql(object value, ColumnInfo mapColumn) => value == null ? "NULL" : string.Concat("N'", value.ToString().Replace("'", "''"), "'"); + public virtual string DateTimeRawSql(object value) + { + if (value == null) return "NULL"; + if (value.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); + return string.Concat("'", ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss"), "'"); + } + public virtual string TimeSpanRawSql(object value) => value == null ? "NULL" : ((TimeSpan)value).TotalSeconds.ToString(); + public virtual string ByteRawSql(object value) + { + if (value == null) return "NULL"; + return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; + } + + public virtual string CastSql(string sql, string to) => $"cast({sql} as {to})"; + public virtual string IsNullSql(string sql, object value) => $"isnull({sql}, {value})"; + public virtual string ConcatSql(string[] objs, Type[] types) + { + var sb = new StringBuilder(); + var news = new string[objs.Length]; + for (var a = 0; a < objs.Length; a++) + { + if (types[a] == typeof(string)) news[a] = objs[a]; + else if (types[a].NullableTypeOrThis() == typeof(Guid)) news[a] = $"cast({objs[a]} as char(36))"; + else news[a] = $"cast({objs[a]} as nvarchar)"; + } + return string.Join(" + ", news); + } + + public virtual string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public virtual string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + + public virtual string LambdaConvert_ToBoolean(Type type, string operand) => $"(cast({operand} as varchar) not in ('0','false'))"; + public virtual string LambdaConvert_ToByte(Type type, string operand) => $"cast({operand} as tinyint)"; + public virtual string LambdaConvert_ToChar(Type type, string operand) => $"substring(cast({operand} as varchar),1,1)"; + public virtual string LambdaConvert_ToDateTime(Type type, string operand) => $"cast({operand} as datetime)"; + public virtual string LambdaConvert_ToDecimal(Type type, string operand) => $"cast({operand} as decimal(36,18))"; + public virtual string LambdaConvert_ToDouble(Type type, string operand) => $"cast({operand} as decimal(32,16))"; + public virtual string LambdaConvert_ToInt16(Type type, string operand) => $"cast({operand} as smallint)"; + public virtual string LambdaConvert_ToInt32(Type type, string operand) => $"cast({operand} as int)"; + public virtual string LambdaConvert_ToInt64(Type type, string operand) => $"cast({operand} as bigint)"; + public virtual string LambdaConvert_ToSByte(Type type, string operand) => $"cast({operand} as tinyint)"; + public virtual string LambdaConvert_ToSingle(Type type, string operand) => $"cast({operand} as decimal(14,7))"; + public virtual string LambdaConvert_ToString(Type type, string operand) => type.NullableTypeOrThis() == typeof(Guid) ? $"cast({operand} as varchar(36))" : $"cast({operand} as nvarchar)"; + public virtual string LambdaConvert_ToUInt16(Type type, string operand) => $"cast({operand} as smallint)"; + public virtual string LambdaConvert_ToUInt32(Type type, string operand) => $"cast({operand} as int)"; + public virtual string LambdaConvert_ToUInt64(Type type, string operand) => $"cast({operand} as bigint)"; + public virtual string LambdaConvert_ToGuid(Type type, string operand) => $"cast({operand} as uniqueidentifier)"; + + public virtual string LambdaGuid_NewGuid => "newid()"; + public virtual string LambdaRandom_Next => "cast(rand()*1000000000 as int)"; + public virtual string LambdaRandom_NextDouble => "rand()"; + + public virtual string LambdaString_IsNullOrEmpty(string operand) => $"({operand} is null or {operand} = '')"; + public virtual string LambdaString_IsNullOrWhiteSpace(string operand) => $"({operand} is null or {operand} = '' or ltrim({operand}) = '')"; + public virtual string LambdaString_Length(string operand) => $"len({operand})"; + + public virtual string LambdaString_ToLower(string operand) => $"lower({operand})"; + public virtual string LambdaString_ToUpper(string operand) => $"upper({operand})"; + public virtual string LambdaString_Substring(string operand, string startIndex, string length) => string.IsNullOrEmpty(length) ? $"left({operand}, {startIndex})" : $"substring({operand}, {startIndex}, {length})"; + public virtual string LambdaString_IndexOf(string operand, string value, string startIndex) => string.IsNullOrEmpty(startIndex) ? $"(charindex({value}, {operand})-1)" : $"(charindex({value}, {operand}, {startIndex})-1)"; + public virtual string LambdaString_PadLeft(string operand, string length, string paddingChar) => string.IsNullOrEmpty(paddingChar) ? $"lpad({operand}, {length})" : $"lpad({operand}, {length}, {paddingChar})"; + public virtual string LambdaString_PadRight(string operand, string length, string paddingChar) => string.IsNullOrEmpty(paddingChar) ? $"rpad({operand}, {length})" : $"rpad({operand}, {length}, {paddingChar})"; + public virtual string LambdaString_Trim(string operand) => $"ltrim(rtrim({operand}))"; + public virtual string LambdaString_TrimStart(string operand) => $"ltrim({operand})"; + public virtual string LambdaString_TrimEnd(string operand) => $"rtrim({operand})"; + public virtual string LambdaString_Replace(string operand, string oldValue, string newValue) => $"replace({operand}, {oldValue}, {newValue})"; + public virtual string LambdaString_CompareTo(string operand, string value) => $"({operand} - {value})"; + public virtual string LambdaString_Equals(string operand, string value) => $"({operand} = {value})"; + + public virtual string LambdaDateTime_Now => "getdate()"; + public virtual string LambdaDateTime_UtcNow => "getutcdate()"; + public virtual string LambdaDateTime_Today => "convert(char(10),getdate(),120)"; + public virtual string LambdaDateTime_MinValue => "'1753/1/1 0:00:00'"; + public virtual string LambdaDateTime_MaxValue => "'9999/12/31 23:59:59'"; + public virtual string LambdaDateTime_Date(string operand) => $"convert(char(10),{operand},120)"; + public virtual string LambdaDateTime_TimeOfDay(string operand) => $"datediff(second, convert(char(10),{operand},120), {operand})"; + public virtual string LambdaDateTime_DayOfWeek(string operand) => $"(datepart(weekday, {operand})-1)"; + public virtual string LambdaDateTime_Day(string operand) => $"datepart(day, {operand})"; + public virtual string LambdaDateTime_DayOfYear(string operand) => $"datepart(dayofyear, {operand})"; + public virtual string LambdaDateTime_Month(string operand) => $"datepart(month, {operand})"; + public virtual string LambdaDateTime_Year(string operand) => $"datepart(year, {operand})"; + public virtual string LambdaDateTime_Hour(string operand) => $"datepart(hour, {operand})"; + public virtual string LambdaDateTime_Minute(string operand) => $"datepart(minute, {operand})"; + public virtual string LambdaDateTime_Second(string operand) => $"datepart(second, {operand})"; + public virtual string LambdaDateTime_Millisecond(string operand) => $"(datepart(millisecond, {operand})/1000)"; + public virtual string LambdaDateTime_Ticks(string operand) => $"(cast(datediff(second, '1970-1-1', {operand}) as bigint)*10000000+621355968000000000)"; + + public virtual string LambdaDateTime_DaysInMonth(string year, string month) => $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({year} as varchar) + '-' + cast({month} as varchar) + '-1')))"; + public virtual string LambdaDateTime_IsLeapYear(string year) => $"(({year})%4=0 AND ({year})%100<>0 OR ({year})%400=0)"; + public virtual string LambdaDateTime_Add(string operand, string value) => $"dateadd(second, {value}, {operand})"; + public virtual string LambdaDateTime_AddDays(string operand, string value) => $"dateadd(day, {value}, {operand})"; + public virtual string LambdaDateTime_AddHours(string operand, string value) => $"dateadd(hour, {value}, {operand})"; + public virtual string LambdaDateTime_AddMilliseconds(string operand, string value) => $"dateadd(second, ({value})/1000, {operand})"; + public virtual string LambdaDateTime_AddMinutes(string operand, string value) => $"dateadd(minute, {value}, {operand})"; + public virtual string LambdaDateTime_AddMonths(string operand, string value) => $"dateadd(month, {value}, {operand})"; + public virtual string LambdaDateTime_AddSeconds(string operand, string value) => $"dateadd(second, {value}, {operand})"; + public virtual string LambdaDateTime_AddTicks(string operand, string value) => $"dateadd(second, ({value})/10000000, {operand})"; + public virtual string LambdaDateTime_AddYears(string operand, string value) => $"dateadd(year, {value}, {operand})"; + public virtual string LambdaDateTime_Subtract(string operand, string value) => $"datediff(second, {value}, {operand})"; + public virtual string LambdaDateTime_SubtractTimeSpan(string operand, string value) => $"dateadd(second, ({value})*-1, {operand})"; + public virtual string LambdaDateTime_Equals(string operand, string value) => $"({operand} = {value})"; + public virtual string LambdaDateTime_CompareTo(string operand, string value) => $"datediff(second,{value},{operand})"; + public virtual string LambdaDateTime_ToString(string operand) => $"convert(varchar, {operand}, 121)"; + + public virtual string LambdaMath_Abs(string operand) => $"abs({operand})"; + public virtual string LambdaMath_Sign(string operand) => $"sign({operand})"; + public virtual string LambdaMath_Floor(string operand) => $"floor({operand})"; + public virtual string LambdaMath_Ceiling(string operand) => $"ceiling({ operand})"; + public virtual string LambdaMath_Round(string operand, string decimals) => $"round({operand}, {decimals})"; + public virtual string LambdaMath_Exp(string operand) => $"exp({operand})"; + public virtual string LambdaMath_Log(string operand) => $"log({operand})"; + public virtual string LambdaMath_Log10(string operand) => $"log10({operand})"; + public virtual string LambdaMath_Pow(string operand, string y) => $"power({operand}, {y})"; + public virtual string LambdaMath_Sqrt(string operand) => $"sqrt({operand})"; + public virtual string LambdaMath_Cos(string operand) => $"cos({operand})"; + public virtual string LambdaMath_Sin(string operand) => $"sin({operand})"; + public virtual string LambdaMath_Tan(string operand) => $"tan({operand})"; + public virtual string LambdaMath_Acos(string operand) => $"acos({operand})"; + public virtual string LambdaMath_Asin(string operand) => $"asin({operand})"; + public virtual string LambdaMath_Atan(string operand) => $"atan({operand})"; + public virtual string LambdaMath_Atan2(string operand, string x) => $"atan2({operand}, {x})"; + public virtual string LambdaMath_Truncate(string operand) => $"floor({operand})"; + } +} diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs index 8fe08329..45a1cb26 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs @@ -1,6 +1,10 @@ using FreeSql.Internal; using FreeSql.Internal.Model; +#if oledb +using System.Data.OleDb; +#else using Oracle.ManagedDataAccess.Client; +#endif using System; using System.Collections.Generic; using System.Data; @@ -194,7 +198,7 @@ namespace FreeSql.Oracle.Curd return 0; } var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); - var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0) as OracleParameter; + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0); identParam.Direction = ParameterDirection.Output; sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); @@ -263,7 +267,7 @@ namespace FreeSql.Oracle.Curd return 0; } var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); - var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0) as OracleParameter; + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0); identParam.Direction = ParameterDirection.Output; sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; var dbParms = _params.Concat(new[] { identParam }).ToArray(); diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index 3afc7fb2..fa0bd1ce 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -1,11 +1,9 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using Oracle.ManagedDataAccess.Client; using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; -using System.Text; using System.Threading; namespace FreeSql.Oracle @@ -63,8 +61,13 @@ namespace FreeSql.Oracle public override DbCommand CreateCommand() { - var cmd = new OracleCommand(); + var cmd = +#if oledb + new System.Data.OleDb.OleDbCommand(); +#else + new Oracle.ManagedDataAccess.Client.OracleCommand(); cmd.BindByName = true; +#endif return cmd; } diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs index 960f601c..7c172437 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs @@ -1,11 +1,15 @@ -using Oracle.ManagedDataAccess.Client; +#if oledb +using System.Data.OleDb; +using OracleException = System.Data.OleDb.OleDbException; +using OracleConnection = System.Data.OleDb.OleDbConnection; +#else +using Oracle.ManagedDataAccess.Client; +#endif using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Data; using System.Data.Common; -using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; @@ -121,7 +125,10 @@ namespace FreeSql.Oracle public void OnDestroy(DbConnection obj) { try { if (obj.State != ConnectionState.Closed) obj.Close(); } catch { } +#if oledb +#else try { OracleConnection.ClearPool(obj as OracleConnection); } catch { } +#endif obj.Dispose(); } diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 86a19c13..8c756dcc 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -2,7 +2,11 @@ using FreeSql.DatabaseModel; using FreeSql.Internal; using FreeSql.Internal.Model; +#if oledb +using System.Data.OleDb; +#else using Oracle.ManagedDataAccess.Client; +#endif using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -21,37 +25,67 @@ namespace FreeSql.Oracle public OracleCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } static object _dicCsToDbLock = new object(); - static Dictionary> _dicCsToDb = new Dictionary>() { - { typeof(bool).FullName, CsToDb.New(OracleDbType.Boolean, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(OracleDbType.Boolean, "number","number(1) NULL", null, true, null) }, +#if oledb + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool), CsToDb.New(OleDbType.Boolean, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?), CsToDb.New(OleDbType.Boolean, "number","number(1) NULL", null, true, null) }, - { typeof(sbyte).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(4) NULL", false, true, null) }, - { typeof(short).FullName, CsToDb.New(OracleDbType.Int16, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(OracleDbType.Int16, "number", "number(6) NULL", false, true, null) }, - { typeof(int).FullName, CsToDb.New(OracleDbType.Int32, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(OracleDbType.Int32, "number", "number(11) NULL", false, true, null) }, - { typeof(long).FullName, CsToDb.New(OracleDbType.Int64, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(OracleDbType.Int64, "number","number(21) NULL", false, true, null) }, + { typeof(sbyte), CsToDb.New(OleDbType.TinyInt, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?), CsToDb.New(OleDbType.TinyInt, "number", "number(4) NULL", false, true, null) }, + { typeof(short), CsToDb.New(OleDbType.SmallInt, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?), CsToDb.New(OleDbType.SmallInt, "number", "number(6) NULL", false, true, null) }, + { typeof(int), CsToDb.New(OleDbType.Integer, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?), CsToDb.New(OleDbType.Integer, "number", "number(11) NULL", false, true, null) }, + { typeof(long), CsToDb.New(OleDbType.BigInt, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?), CsToDb.New(OleDbType.BigInt, "number","number(21) NULL", false, true, null) }, - { typeof(byte).FullName, CsToDb.New(OracleDbType.Byte, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(OracleDbType.Byte, "number","number(3) NULL", true, true, null) }, - { typeof(ushort).FullName, CsToDb.New(OracleDbType.Decimal, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(5) NULL", true, true, null) }, - { typeof(uint).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(10) NULL", true, true, null) }, - { typeof(ulong).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(20) NULL", true, true, null) }, + { typeof(byte), CsToDb.New(OleDbType.UnsignedTinyInt, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?), CsToDb.New(OleDbType.UnsignedTinyInt, "number","number(3) NULL", true, true, null) }, + { typeof(ushort), CsToDb.New(OleDbType.UnsignedSmallInt, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?), CsToDb.New(OleDbType.UnsignedSmallInt, "number", "number(5) NULL", true, true, null) }, + { typeof(uint), CsToDb.New(OleDbType.UnsignedInt, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?), CsToDb.New(OleDbType.UnsignedInt, "number", "number(10) NULL", true, true, null) }, + { typeof(ulong), CsToDb.New(OleDbType.UnsignedBigInt, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?), CsToDb.New(OleDbType.UnsignedBigInt, "number", "number(20) NULL", true, true, null) }, - { typeof(double).FullName, CsToDb.New(OracleDbType.Double, "float", "float(126) NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(OracleDbType.Double, "float", "float(126) NULL", false, true, null) }, - { typeof(float).FullName, CsToDb.New(OracleDbType.Single, "float","float(63) NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(OracleDbType.Single, "float","float(63) NULL", false, true, null) }, - { typeof(decimal).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(OracleDbType.Decimal, "number", "number(10,2) NULL", false, true, null) }, + { typeof(double), CsToDb.New(OleDbType.Double, "float", "float(126) NOT NULL", false, false, 0) },{ typeof(double?), CsToDb.New(OleDbType.Double, "float", "float(126) NULL", false, true, null) }, + { typeof(float), CsToDb.New(OleDbType.Single, "float","float(63) NOT NULL", false, false, 0) },{ typeof(float?), CsToDb.New(OleDbType.Single, "float","float(63) NULL", false, true, null) }, + { typeof(decimal), CsToDb.New(OleDbType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?), CsToDb.New(OleDbType.Decimal, "number", "number(10,2) NULL", false, true, null) }, - { typeof(TimeSpan).FullName, CsToDb.New(OracleDbType.IntervalDS, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(OracleDbType.IntervalDS, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, - { typeof(DateTime).FullName, CsToDb.New(OracleDbType.TimeStamp, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(OracleDbType.TimeStamp, "timestamp", "timestamp(6) NULL", false, true, null) }, - { typeof(DateTimeOffset).FullName, CsToDb.New(OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, CsToDb.New(OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) }, + { typeof(TimeSpan), CsToDb.New(OleDbType.DBTime, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?), CsToDb.New(OleDbType.DBTime, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, + { typeof(DateTime), CsToDb.New(OleDbType.DBTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?), CsToDb.New(OleDbType.DBTime, "timestamp", "timestamp(6) NULL", false, true, null) }, + { typeof(DateTimeOffset), CsToDb.New(OleDbType.DBTimeStamp, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?), CsToDb.New(OleDbType.DBTimeStamp, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) }, - { typeof(byte[]).FullName, CsToDb.New(OracleDbType.Blob, "blob", "blob NULL", false, null, new byte[0]) }, - { typeof(string).FullName, CsToDb.New(OracleDbType.NVarchar2, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, - { typeof(char).FullName, CsToDb.New(OracleDbType.Char, "char", "char(1 CHAR) NULL", false, null, '\0') }, + { typeof(byte[]), CsToDb.New(OleDbType.VarBinary, "blob", "blob NULL", false, null, new byte[0]) }, + { typeof(string), CsToDb.New(OleDbType.VarChar, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + { typeof(char), CsToDb.New(OleDbType.Char, "char", "char(1 CHAR) NULL", false, null, '\0') }, - { typeof(Guid).FullName, CsToDb.New(OracleDbType.Char, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(OracleDbType.Char, "char", "char(36 CHAR) NULL", false, true, null) }, + { typeof(Guid), CsToDb.New(OleDbType.Char, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?), CsToDb.New(OleDbType.Char, "char", "char(36 CHAR) NULL", false, true, null) }, }; +#else + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool), CsToDb.New(OracleDbType.Boolean, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?), CsToDb.New(OracleDbType.Boolean, "number","number(1) NULL", null, true, null) }, + + { typeof(sbyte), CsToDb.New(OracleDbType.Decimal, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?), CsToDb.New(OracleDbType.Decimal, "number", "number(4) NULL", false, true, null) }, + { typeof(short), CsToDb.New(OracleDbType.Int16, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?), CsToDb.New(OracleDbType.Int16, "number", "number(6) NULL", false, true, null) }, + { typeof(int), CsToDb.New(OracleDbType.Int32, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?), CsToDb.New(OracleDbType.Int32, "number", "number(11) NULL", false, true, null) }, + { typeof(long), CsToDb.New(OracleDbType.Int64, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?), CsToDb.New(OracleDbType.Int64, "number","number(21) NULL", false, true, null) }, + + { typeof(byte), CsToDb.New(OracleDbType.Byte, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?), CsToDb.New(OracleDbType.Byte, "number","number(3) NULL", true, true, null) }, + { typeof(ushort), CsToDb.New(OracleDbType.Decimal, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?), CsToDb.New(OracleDbType.Decimal, "number", "number(5) NULL", true, true, null) }, + { typeof(uint), CsToDb.New(OracleDbType.Decimal, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?), CsToDb.New(OracleDbType.Decimal, "number", "number(10) NULL", true, true, null) }, + { typeof(ulong), CsToDb.New(OracleDbType.Decimal, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?), CsToDb.New(OracleDbType.Decimal, "number", "number(20) NULL", true, true, null) }, + + { typeof(double), CsToDb.New(OracleDbType.Double, "float", "float(126) NOT NULL", false, false, 0) },{ typeof(double?), CsToDb.New(OracleDbType.Double, "float", "float(126) NULL", false, true, null) }, + { typeof(float), CsToDb.New(OracleDbType.Single, "float","float(63) NOT NULL", false, false, 0) },{ typeof(float?), CsToDb.New(OracleDbType.Single, "float","float(63) NULL", false, true, null) }, + { typeof(decimal), CsToDb.New(OracleDbType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?), CsToDb.New(OracleDbType.Decimal, "number", "number(10,2) NULL", false, true, null) }, + + { typeof(TimeSpan), CsToDb.New(OracleDbType.IntervalDS, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?), CsToDb.New(OracleDbType.IntervalDS, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, + { typeof(DateTime), CsToDb.New(OracleDbType.TimeStamp, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?), CsToDb.New(OracleDbType.TimeStamp, "timestamp", "timestamp(6) NULL", false, true, null) }, + { typeof(DateTimeOffset), CsToDb.New(OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?), CsToDb.New(OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) }, + + { typeof(byte[]), CsToDb.New(OracleDbType.Blob, "blob", "blob NULL", false, null, new byte[0]) }, + { typeof(string), CsToDb.New(OracleDbType.NVarchar2, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + { typeof(char), CsToDb.New(OracleDbType.Char, "char", "char(1 CHAR) NULL", false, null, '\0') }, + + { typeof(Guid), CsToDb.New(OracleDbType.Char, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?), CsToDb.New(OracleDbType.Char, "char", "char(36 CHAR) NULL", false, true, null) }, + }; +#endif public override DbInfoResult GetDbInfo(Type type) { - if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); + if (_dicCsToDb.TryGetValue(type, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); if (type.IsArray) return null; var enumType = type.IsEnum ? type : null; if (enumType == null && type.IsNullableType()) @@ -62,14 +96,14 @@ namespace FreeSql.Oracle if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - CsToDb.New(OracleDbType.Int32, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : - CsToDb.New(OracleDbType.Int64, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); - if (_dicCsToDb.ContainsKey(type.FullName) == false) + CsToDb.New(_dicCsToDb[typeof(int)].type, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(_dicCsToDb[typeof(long)].type, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); + if (_dicCsToDb.ContainsKey(type) == false) { lock (_dicCsToDbLock) { - if (_dicCsToDb.ContainsKey(type.FullName) == false) - _dicCsToDb.Add(type.FullName, newItem); + if (_dicCsToDb.ContainsKey(type) == false) + _dicCsToDb.Add(type, newItem); } } return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); diff --git a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs index 9262cdf1..9351e7fa 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleDbFirst.cs @@ -1,7 +1,11 @@ using FreeSql.DatabaseModel; using FreeSql.Internal; using FreeSql.Internal.Model; +#if oledb +using System.Data.OleDb; +#else using Oracle.ManagedDataAccess.Client; +#endif using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -25,6 +29,98 @@ namespace FreeSql.Oracle } public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); +#if oledb + OleDbType GetSqlDbType(DbColumnInfo column) + { + var dbfull = column.DbTypeTextFull?.ToLower(); + switch (dbfull) + { + case "number(1)": return OleDbType.Boolean; + + case "number(4)": return OleDbType.TinyInt; + case "number(6)": return OleDbType.SmallInt; + case "number(11)": return OleDbType.Integer; + case "number(21)": return OleDbType.BigInt; + + case "number(3)": return OleDbType.UnsignedTinyInt; + case "number(5)": return OleDbType.UnsignedSmallInt; + case "number(10)": return OleDbType.UnsignedInt; + case "number(20)": return OleDbType.UnsignedBigInt; + + case "float(126)": return OleDbType.Double; + case "float(63)": return OleDbType.Single; + case "number(10,2)": return OleDbType.Decimal; + + case "interval day(2) to second(6)": return OleDbType.DBTime; + case "timestamp(6)": return OleDbType.DBTime; + case "timestamp(6) with local time zone": return OleDbType.DBTimeStamp; + + case "blob": return OleDbType.VarBinary; + case "nvarchar2(255)": return OleDbType.VarChar; + + case "char(36 char)": return OleDbType.Char; + } + switch (column.DbTypeText?.ToLower()) + { + case "number": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(10,2)"]); + return OleDbType.Decimal; + case "float": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); + return OleDbType.Double; + case "interval day to second": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["interval day(2) to second(6)"]); + return OleDbType.DBTime; + case "date": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["date"]); + return OleDbType.DBTime; + case "timestamp": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6)"]); + return OleDbType.DBTime; + case "timestamp with local time zone": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6) with local time zone"]); + return OleDbType.DBTimeStamp; + case "blob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return OleDbType.VarBinary; + case "nvarchar2": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OleDbType.VarChar; + case "varchar2": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OleDbType.VarChar; + case "char": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OleDbType.Char; + case "nchar": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OleDbType.Char; + case "clob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OleDbType.VarChar; + case "nclob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OleDbType.VarChar; + case "raw": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return OleDbType.VarBinary; + case "long raw": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return OleDbType.VarBinary; + case "binary_float": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(63)"]); + return OleDbType.Single; + case "binary_double": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); + return OleDbType.Double; + case "rowid": + default: + if (dbfull != null) _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return OleDbType.VarChar; + } + throw new NotImplementedException(CoreStrings.S_TypeMappingNotImplemented(column.DbTypeTextFull)); + } +#else OracleDbType GetSqlDbType(DbColumnInfo column) { var dbfull = column.DbTypeTextFull?.ToLower(); @@ -115,6 +211,7 @@ namespace FreeSql.Oracle } throw new NotImplementedException(CoreStrings.S_TypeMappingNotImplemented(column.DbTypeTextFull)); } +#endif static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); static OracleDbFirst() diff --git a/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs b/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs index f4982912..c3409da5 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExtensions.cs @@ -1,5 +1,9 @@ using FreeSql; +#if oledb +using System.Data.OleDb; +#else using Oracle.ManagedDataAccess.Client; +#endif using System; public static partial class FreeSqlOracleGlobalExtensions @@ -14,6 +18,8 @@ public static partial class FreeSqlOracleGlobalExtensions public static string FormatOracle(this string that, params object[] args) => _oracleAdo.Addslashes(that, args); static FreeSql.Oracle.OracleAdo _oracleAdo = new FreeSql.Oracle.OracleAdo(); +#if oledb +#else #region ExecuteOracleBulkCopy /// /// Oracle CopyBulk 批量插入功能 @@ -106,4 +112,5 @@ public static partial class FreeSqlOracleGlobalExtensions } } #endregion +#endif } diff --git a/Providers/FreeSql.Provider.OracleOledb/FreeSql.Provider.OracleOledb.csproj b/Providers/FreeSql.Provider.OracleOledb/FreeSql.Provider.OracleOledb.csproj new file mode 100644 index 00000000..27904414 --- /dev/null +++ b/Providers/FreeSql.Provider.OracleOledb/FreeSql.Provider.OracleOledb.csproj @@ -0,0 +1,52 @@ + + + + netstandard2.0;net45;net40 + true + FreeSql;ncc;YeXiangQin + FreeSql 数据库 Oracle 基于 oledb 实现,解决 US7ASCII 中文乱码问题 + https://github.com/2881099/FreeSql + https://github.com/2881099/FreeSql + git + MIT + FreeSql;ORM;Oracle;Oledb;US7ASCII + $(AssemblyName) + logo.png + $(AssemblyName) + true + true + true + key.snk + false + 3.2.666-preview20220823 + + + + + + + + + + + + + + + + + + + + + + + oledb + + + + net40;oledb + + + + diff --git a/Providers/FreeSql.Provider.OracleOledb/OracleOledbUtils.cs b/Providers/FreeSql.Provider.OracleOledb/OracleOledbUtils.cs new file mode 100644 index 00000000..1bea6e9e --- /dev/null +++ b/Providers/FreeSql.Provider.OracleOledb/OracleOledbUtils.cs @@ -0,0 +1,156 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data.OleDb; +using System.Data.Common; +using System.Globalization; + +namespace FreeSql.Oracle +{ + + class OracleUtils : CommonUtils + { + public OracleUtils(IFreeSql orm) : base(orm) + { + } + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + var dbtype = (OleDbType?)_orm.CodeFirst.GetDbInfo(type)?.type; + if (dbtype == OleDbType.Boolean) + { + if (value == null) value = null; + else value = (bool)value == true ? 1 : 0; + dbtype = OleDbType.SmallInt; + } + var ret = new OleDbParameter { ParameterName = QuoteParamterName(parameterName) }; + if (dbtype != null) ret.OleDbType = dbtype.Value; + ret.Value = value; + if (col != null) + { + var dbtype2 = (OleDbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeTextFull = col.Attribute.DbType?.Replace("NOT NULL", "").Replace(" NULL", "").Trim(), DbTypeText = col.DbTypeText }); + switch (dbtype2) + { + case OleDbType.Char: + case OleDbType.VarChar: + case OleDbType.WChar: + case OleDbType.LongVarChar: + case OleDbType.LongVarWChar: + case OleDbType.Decimal: + dbtype = dbtype2; + //if (col.DbSize != 0) ret.Size = col.DbSize; + if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; + if (col.DbScale != 0) ret.Scale = col.DbScale; + break; + } + } + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, ":", (name, type, value) => + { + var dbtypeint = _orm.CodeFirst.GetDbInfo(type)?.type; + var dbtype = dbtypeint != null ? (OleDbType?)dbtypeint : null; + if (dbtype == OleDbType.Boolean) + { + if (value == null) value = null; + else value = (bool)value == true ? 1 : 0; + dbtype = OleDbType.SmallInt; + } + var ret = new OleDbParameter { ParameterName = $":{name}" }; + if (dbtype != null) ret.OleDbType = dbtype.Value; + if (value is IList valueList && value is Array == false && valueList.Count > 0) + { + var valueItemType = valueList[0]?.GetType(); + if (valueItemType == typeof(int)) LocalSetListValue(); + else if (valueItemType == typeof(long)) LocalSetListValue(); + else if (valueItemType == typeof(short)) LocalSetListValue(); + else if (valueItemType == typeof(string)) LocalSetListValue(); + else if (valueItemType == typeof(Guid)) LocalSetListValue(); + else if (valueItemType == typeof(char)) LocalSetListValue(); + else if (valueItemType == typeof(bool)) LocalSetListValue(); + else if (valueItemType == typeof(uint)) LocalSetListValue(); + else if (valueItemType == typeof(ulong)) LocalSetListValue(); + else if (valueItemType == typeof(ushort)) LocalSetListValue(); + else if (valueItemType == typeof(decimal)) LocalSetListValue(); + else if (valueItemType == typeof(double)) LocalSetListValue(); + else if (valueItemType == typeof(float)) LocalSetListValue(); + else if (valueItemType == typeof(DateTime)) LocalSetListValue(); + + void LocalSetListValue() + { + var valueCopy = new List(); + foreach (var valueItem in valueList) valueCopy.Add((T)Utils.GetDataReaderValue(valueItemType, valueItem)); + value = valueCopy.ToArray(); + } + } + ret.Value = value; //IList 赋值会报错 + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatOracle(args); + public override string QuoteSqlName(params string[] name) + { + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); + public override string QuoteParamterName(string name) => $":{name}"; + public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"trunc({left} / {right})"; + public override string Now => "systimestamp"; + public override string NowUtc => "sys_extract_utc(systimestamp)"; + + public override string QuoteWriteParamterAdapter(Type type, string paramterName) => paramterName; + protected override string QuoteReadColumnAdapter(Type type, Type mapType, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) + { + if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); + if (type == typeof(string)) + { + var valueString = value as string; + if (valueString != null) + { + if (valueString.Length < 4000) return string.Concat("'", valueString.Replace("'", "''"), "'"); + var pam = AppendParamter(specialParams, $"p_{specialParams?.Count}{specialParamFlag}", col, type, value); + return pam.ParameterName; + } + } + if (type == typeof(byte[])) + { + var valueBytes = value as byte[]; + if (valueBytes != null) + { + if (valueBytes.Length < 4000) return $"hextoraw('{CommonUtils.BytesSqlRaw(valueBytes)}')"; + var pam = AppendParamter(specialParams, $"p_{specialParams?.Count}{specialParamFlag}", col, type, value); + return pam.ParameterName; + } + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.OracleOledb/key.snk b/Providers/FreeSql.Provider.OracleOledb/key.snk new file mode 100644 index 0000000000000000000000000000000000000000..ee20b4b1a0815eac842bc01d4becaa8814ae0b14 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50097nKW;Q)(l0*2_LP37mJV1_SL_wJp_%19 zz}Ioucr4R)UNZq%r-$=RryFiI8)w!j<{z)y2~@p##L$SPx^Ow#GA*zK`{`cfYL7{l+Kxddb$Rvhs&7lm@`8>uzw0+OE7j#mY{c`qYhBLw zcTGv3<(P)_%zO>@*n(qI-%i9l@ajAusufL6g2Vv#NI96{=y#u{9B_yQKTPz)Y1$HZ zD>)q$vf8;gu0YshJ#~JP;~%_{2fSYfOELVZHBw(!Q9B`pKjDnCeY`_d!%4(WhMfK$ zib<3?gsgWm`U%MfEU6k^$B1oKeoOR+6Ka49G&ay?N* zWrr4(9T)d$I0G(sI2kIll6}TqEoiT#l$9WiCiIHArG(J)@}oPH&x7=*Q#zIO2)&${ zs=8;1+&r`77n1*!D3-|5;1jS&VG_ExzZ)Nhn^BcViCiS4rX}W|LSx7qNZbgPU3FF1 zjjOa|%br?&bZxd+I~%#VD@?Y)q9}!bhgyA-Znito|8TOd$`r z#f$F8O#2i?@t)1AqE6%gl3yp72kFp8Z&aePj>(S716o zDo}MQ0!f+r8b6a|9OKhVLMi>I(pfb~lkYJ>SkhIf*VGAzeZPoUrp+NtlKmiYU*A)1 iK9<^9bbhHh%Datqpbh^L1ZmM}I29}Y1xF)Q!$<>NydEt8 literal 0 HcmV?d00001