From 9711b1d9a8c3b01d64ca4474dd437a44d9cf4a75 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 26 Dec 2018 21:18:59 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=98=A0=E5=B0=84=E5=B0=8F?= =?UTF-8?q?=E5=8A=9F=E5=91=8A=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Docs/codefirst.md | 9 +-- .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 2 +- .../SqlServer/SqlServerCodeFirstTest.cs | 3 +- FreeSql/Internal/Utils.cs | 70 ++++++++++++++++++- 4 files changed, 74 insertions(+), 10 deletions(-) diff --git a/Docs/codefirst.md b/Docs/codefirst.md index b5185781..35a5dbef 100644 --- a/Docs/codefirst.md +++ b/Docs/codefirst.md @@ -41,10 +41,10 @@ | (IPAddress Address, int Subnet) \| (IPAddress Address, int Subnet)? | - | - | cidr | | IPAddress | - | - | inet | | PhysicalAddress | - | - | macaddr | -| NpgsqlRange \| NpgsqlRange? | - | - | int4range | -| NpgsqlRange \| NpgsqlRange? | - | - | int8range | -| NpgsqlRange \| NpgsqlRange? | - | - | numrange | -| NpgsqlRange \| NpgsqlRange? | - | - | tsrange | +| NpgsqlRange\ \| NpgsqlRange\? | - | - | int4range | +| NpgsqlRange\ \| NpgsqlRange\? | - | - | int8range | +| NpgsqlRange\ \| NpgsqlRange\? | - | - | numrange | +| NpgsqlRange\ \| NpgsqlRange\? | - | - | tsrange | | PostgisPoint | - | - | geometry | | PostgisLineString | - | - | geometry | | PostgisPolygon | - | - | geometry | @@ -52,6 +52,7 @@ | PostgisMultiLineString | - | - | geometry | | PostgisMultiPolygon | - | - | geometry | | PostgisGeometry | - | - | geometry | +| PostgisGeometryCollection | - | - | geometry | | Dictionary | - | - | hstore | | JToken | - | - | jsonb | | JObject | - | - | jsonb | diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs index 70d595ba..ae93b593 100644 --- a/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs +++ b/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -275,7 +275,7 @@ namespace FreeSql.Tests.PostgreSQL { testFielLongArrayNullable = new long?[] { 500, 600, 700, null, 999, 1000 }, testFielLongNullable = long.MinValue }; - item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var item3 = insert.AppendData(item2).ExecuteInserted(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); var items = select.ToList(); diff --git a/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index 921b1024..44749891 100644 --- a/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -90,9 +90,8 @@ namespace FreeSql.Tests.SqlServer { testFieldUShort = ushort.MaxValue, testFieldUShortNullable = ushort.MinValue, testFielLongNullable = long.MinValue - }; - item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var item3 = insert.AppendData(item2).ExecuteInserted(); var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); var items = select.ToList(); diff --git a/FreeSql/Internal/Utils.cs b/FreeSql/Internal/Utils.cs index 80969d8f..bc0ebac1 100644 --- a/FreeSql/Internal/Utils.cs +++ b/FreeSql/Internal/Utils.cs @@ -1,11 +1,16 @@ using FreeSql.DataAnnotations; using FreeSql.Internal.Model; using Newtonsoft.Json.Linq; +using Npgsql.LegacyPostgis; +using NpgsqlTypes; using System; +using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Net; +using System.Net.NetworkInformation; using System.Reflection; using System.Text.RegularExpressions; using System.Threading; @@ -92,7 +97,66 @@ namespace FreeSql.Internal { return ret.ToArray(); } + static Dictionary dicExecuteArrayRowReadClassOrTuple = new Dictionary { + { typeof(bool ).FullName, true }, + { typeof(sbyte).FullName, true }, + { typeof(short).FullName, true }, + { typeof(int).FullName, true }, + { typeof(long).FullName, true }, + { typeof(byte).FullName, true }, + { typeof(ushort).FullName, true }, + { typeof(uint).FullName, true }, + { typeof(ulong).FullName, true }, + { typeof(double).FullName, true }, + { typeof(float).FullName, true }, + { typeof(decimal).FullName, true }, + { typeof(TimeSpan).FullName, true }, + { typeof(DateTime).FullName, true }, + { typeof(DateTimeOffset).FullName, true }, + { typeof(byte[]).FullName, true }, + { typeof(string).FullName, true }, + { typeof(Guid).FullName, true }, + { typeof(MygisPoint).FullName, true }, + { typeof(MygisLineString).FullName, true }, + { typeof(MygisPolygon).FullName, true }, + { typeof(MygisMultiPoint).FullName, true }, + { typeof(MygisMultiLineString).FullName, true }, + { typeof(MygisMultiPolygon).FullName, true }, + { typeof(BitArray).FullName, true }, + { typeof(NpgsqlPoint).FullName, true }, + { typeof(NpgsqlLine).FullName, true }, + { typeof(NpgsqlLSeg).FullName, true }, + { typeof(NpgsqlBox).FullName, true }, + { typeof(NpgsqlPath).FullName, true }, + { typeof(NpgsqlPolygon).FullName, true }, + { typeof(NpgsqlCircle).FullName, true }, + { typeof((IPAddress Address, int Subnet)).FullName, true }, + { typeof(IPAddress).FullName, true }, + { typeof(PhysicalAddress).FullName, true }, + { typeof(NpgsqlRange).FullName, true }, + { typeof(NpgsqlRange).FullName, true }, + { typeof(NpgsqlRange).FullName, true }, + { typeof(NpgsqlRange).FullName, true }, + { typeof(PostgisPoint).FullName, true }, + { typeof(PostgisLineString).FullName, true }, + { typeof(PostgisPolygon).FullName, true }, + { typeof(PostgisMultiPoint).FullName, true }, + { typeof(PostgisMultiLineString).FullName, true }, + { typeof(PostgisMultiPolygon).FullName, true }, + { typeof(PostgisGeometry).FullName, true }, + { typeof(PostgisGeometryCollection).FullName, true }, + { typeof(Dictionary).FullName, true }, + { typeof(JToken).FullName, true }, + { typeof(JObject).FullName, true }, + { typeof(JArray).FullName, true }, + }; internal static (object value, int dataIndex) ExecuteArrayRowReadClassOrTuple(Type type, Dictionary names, object[] row, int dataIndex = 0) { + if (type.IsArray) return (GetDataReaderValue(type, row[dataIndex]), dataIndex + 1); + var typeGeneric = type; + if (typeGeneric.FullName.StartsWith("System.Nullable`1[")) typeGeneric = type.GenericTypeArguments.First(); + if (typeGeneric.IsEnum || + dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric.FullName)) + return (GetDataReaderValue(type, row[dataIndex]), dataIndex + 1); if (type.Namespace == "System" && (type.FullName == "System.String" || type.IsValueType)) { //值类型,或者元组 bool isTuple = type.Name.StartsWith("ValueTuple`"); if (isTuple) { @@ -108,7 +172,7 @@ namespace FreeSql.Internal { var constructor = type.GetConstructor(types); return (constructor?.Invoke(parms), dataIndex); } - return (dataIndex >= row.Length || row[dataIndex] == DBNull.Value ? null : Convert.ChangeType(row[dataIndex], type), dataIndex + 1); + return (dataIndex >= row.Length || (row[dataIndex] ?? DBNull.Value) == DBNull.Value ? null : GetDataReaderValue(type, row[dataIndex]), dataIndex + 1); } if (type == typeof(object) && names != null) { dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写 @@ -118,8 +182,7 @@ namespace FreeSql.Internal { return (expando, names.Count); } //类注入属性 - var consturct = type.GetConstructor(new Type[0]); - var value = consturct.Invoke(new object[0]); + var value = type.GetConstructor(new Type[0]).Invoke(new object[0]); var ps = type.GetProperties(); foreach(var p in ps) { var tryidx = dataIndex; @@ -150,6 +213,7 @@ namespace FreeSql.Internal { if (type.IsArray) { var elementType = type.GetElementType(); var valueArr = value as Array; + if (elementType == valueArr.GetType().GetElementType()) return value; var len = valueArr.GetLength(0); var ret = Array.CreateInstance(elementType, len); for (var a = 0; a < len; a++) {