- 优化 pgsql jsonb 映射,支持 List,mysql limit in 子查询;

This commit is contained in:
2881099 2021-11-02 00:38:06 +08:00
parent 65fe03a2ff
commit 3d5ca9bc7e
25 changed files with 192 additions and 22 deletions

View File

@ -1008,6 +1008,14 @@ FROM `tb_topic` a
WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title`
FROM `tb_topic` b)))", subquery); FROM `tb_topic` b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime`
FROM `tb_topic` a
WHERE (((cast(a.`Id` as char)) in ( SELECT * FROM (SELECT b.`Title`
FROM `tb_topic` b
limit 0,10) ftblmt50 )))", subquery);
subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }
[Fact] [Fact]
public void As() public void As()

View File

@ -933,6 +933,14 @@ FROM ""TB_TOPIC22"" a
WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE""
FROM ""TB_TOPIC22"" b)))", subquery); FROM ""TB_TOPIC22"" b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME""
FROM ""TB_TOPIC22"" a
WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE""
FROM ""TB_TOPIC22"" b
WHERE ROWNUM < 11)))", subquery);
subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }
[Fact] [Fact]
public void As() public void As()

View File

@ -1019,6 +1019,14 @@ FROM `tb_topic` a
WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title`
FROM `tb_topic` b)))", subquery); FROM `tb_topic` b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime`
FROM `tb_topic` a
WHERE (((cast(a.`Id` as char)) in ( SELECT * FROM (SELECT b.`Title`
FROM `tb_topic` b
limit 0,10) ftblmt50 )))", subquery);
subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }
[Fact] [Fact]
public void As() public void As()

View File

@ -934,6 +934,14 @@ FROM ""TB_TOPIC22"" a
WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE""
FROM ""TB_TOPIC22"" b)))", subquery); FROM ""TB_TOPIC22"" b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME""
FROM ""TB_TOPIC22"" a
WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE""
FROM ""TB_TOPIC22"" b
WHERE ROWNUM < 11)))", subquery);
subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }
[Fact] [Fact]
public void As() public void As()

View File

@ -995,6 +995,14 @@ FROM ""tb_topic"" a
WHERE ((((a.""id"")::text) in (SELECT b.""title"" WHERE ((((a.""id"")::text) in (SELECT b.""title""
FROM ""tb_topic"" b)))", subquery); FROM ""tb_topic"" b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.""id"", a.""clicks"", a.""typeguid"", a.""title"", a.""createtime""
FROM ""tb_topic"" a
WHERE ((((a.""id"")::text) in (SELECT b.""title""
FROM ""tb_topic"" b
limit 10)))", subquery);
subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }
[Fact] [Fact]
public void As() public void As()

View File

@ -6,7 +6,7 @@ using Xunit;
namespace FreeSql.Tests.AdoNetExtensions.OracleConnectionExtensions { namespace FreeSql.Tests.AdoNetExtensions.OracleConnectionExtensions {
public class Methods { public class Methods {
string _connectString = "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=5"; string _connectString = "user id=1user;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=5";
public Methods() { public Methods() {
g.oracle.CodeFirst.SyncStructure<TestConnectionExt>(); g.oracle.CodeFirst.SyncStructure<TestConnectionExt>();

View File

@ -951,6 +951,14 @@ FROM ""TB_TOPIC22"" a
WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE""
FROM ""TB_TOPIC22"" b)))", subquery); FROM ""TB_TOPIC22"" b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME""
FROM ""TB_TOPIC22"" a
WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE""
FROM ""TB_TOPIC22"" b
WHERE ROWNUM < 11)))", subquery);
subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }
[Fact] [Fact]
public void As() public void As()

View File

@ -934,6 +934,13 @@ FROM ""TB_TOPIC22"" a
WHERE (((cast(a.""ID"" as blob sub_type 1)) in (SELECT b.""TITLE"" WHERE (((cast(a.""ID"" as blob sub_type 1)) in (SELECT b.""TITLE""
FROM ""TB_TOPIC22"" b)))", subquery); FROM ""TB_TOPIC22"" b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME""
FROM ""TB_TOPIC22"" a
WHERE (((cast(a.""ID"" as blob sub_type 1)) in (SELECT FIRST 10 b.""TITLE""
FROM ""TB_TOPIC22"" b)))", subquery);
subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }
[Fact] [Fact]
public void As() public void As()

View File

@ -899,6 +899,13 @@ FROM [tb_topic22] a
WHERE (((cstr(a.[Id])) in (SELECT b.[Title] WHERE (((cstr(a.[Id])) in (SELECT b.[Title]
FROM [tb_topic22] b)))", subquery); FROM [tb_topic22] b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime]
FROM [tb_topic22] a
WHERE (((cstr(a.[Id])) in (SELECT TOP 10 b.[Title]
FROM [tb_topic22] b)))", subquery);
subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }
[Fact] [Fact]
public void As() public void As()

View File

@ -1071,6 +1071,14 @@ FROM `tb_topic` a
WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title`
FROM `tb_topic` b)))", subquery); FROM `tb_topic` b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime`
FROM `tb_topic` a
WHERE (((cast(a.`Id` as char)) in ( SELECT * FROM (SELECT b.`Title`
FROM `tb_topic` b
limit 0,10) ftblmt50 )))", subquery);
subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }
[Fact] [Fact]
public void As() public void As()

View File

@ -938,6 +938,14 @@ FROM ""TB_TOPIC22"" a
WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE""
FROM ""TB_TOPIC22"" b)))", subquery); FROM ""TB_TOPIC22"" b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME""
FROM ""TB_TOPIC22"" a
WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE""
FROM ""TB_TOPIC22"" b
WHERE ROWNUM < 11)))", subquery);
subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }
[Fact] [Fact]
public void As() public void As()

View File

@ -1012,6 +1012,14 @@ FROM ""tb_topic"" a
WHERE ((((a.""id"")::text) in (SELECT b.""title"" WHERE ((((a.""id"")::text) in (SELECT b.""title""
FROM ""tb_topic"" b)))", subquery); FROM ""tb_topic"" b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.""id"", a.""clicks"", a.""typeguid"", a.""title"", a.""createtime""
FROM ""tb_topic"" a
WHERE ((((a.""id"")::text) in (SELECT b.""title""
FROM ""tb_topic"" b
limit 10)))", subquery);
subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }
[Fact] [Fact]
public void As() public void As()

View File

@ -945,6 +945,13 @@ FROM [tb_topic22] a
WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title]
FROM [tb_topic22] b)))", subquery); FROM [tb_topic22] b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime]
FROM [tb_topic22] a
WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT TOP 10 b.[Title]
FROM [tb_topic22] b)))", subquery);
subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }
[Fact] [Fact]
public void As() public void As()

View File

@ -922,6 +922,14 @@ FROM ""tb_topic22"" a
WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title"" WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title""
FROM ""tb_topic22"" b)))", subquery); FROM ""tb_topic22"" b)))", subquery);
var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql();
Assert.Equal(@"SELECT a.""Id"", a.""Clicks"", a.""TypeGuid"", a.""Title"", a.""CreateTime""
FROM ""tb_topic22"" a
WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title""
FROM ""tb_topic22"" b
limit 0,10)))", subquery);
subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList();
} }
[Fact] [Fact]
public void As() public void As()

View File

@ -633,7 +633,7 @@ INNER JOIN ""userinfo"" p ON p.""userid"" = o.""userid""", select16Sql2);
.UseLazyLoading(true) .UseLazyLoading(true)
.Build()); .Build());
ib.Register("db2", () => new FreeSql.FreeSqlBuilder() ib.Register("db2", () => new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=3") .UseConnectionString(FreeSql.DataType.Oracle, "user id=1user;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=3")
.UseAutoSyncStructure(true) .UseAutoSyncStructure(true)
.UseGenerateCommandParameterWithLambda(true) .UseGenerateCommandParameterWithLambda(true)
.UseLazyLoading(true) .UseLazyLoading(true)

View File

@ -3,6 +3,7 @@ using FreeSql.DataAnnotations;
using FreeSql.Internal; using FreeSql.Internal;
using FreeSql.Internal.CommonProvider; using FreeSql.Internal.CommonProvider;
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
using Newtonsoft.Json.Linq;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@ -15,6 +16,35 @@ namespace FreeSql.Tests
{ {
public class UnitTest5 public class UnitTest5
{ {
[Fact]
public void TestJsonb01()
{
var fsql = g.pgsql;
fsql.Delete<TestJsonb01Cls1>().Where("1=1").ExecuteAffrows();
var item = new TestJsonb01Cls1
{
jsonb01 = new List<int> { 1, 5, 10, 20 },
jsonb02 = new List<long> { 11, 51, 101, 201 },
jsonb03 = new List<string> { "12", "52", "102", "202" },
};
fsql.Insert(item).ExecuteAffrows();
var items = fsql.Select<TestJsonb01Cls1>().ToList();
}
public class TestJsonb01Cls1
{
public Guid id { get; set; }
[Column(MapType = typeof(JArray))]
public List<int> jsonb01 { get; set; }
[Column(MapType = typeof(JToken))]
public List<long> jsonb02 { get; set; }
[Column(MapType = typeof(JToken))]
public List<string> jsonb03 { get; set; }
}
[Fact] [Fact]
public void DebugUpdateSet01() public void DebugUpdateSet01()
{ {

View File

@ -378,6 +378,7 @@ namespace FreeSql.Internal
objval = Utils.GetDataReaderValue(parent.CsType, objval); objval = Utils.GetDataReaderValue(parent.CsType, objval);
if (parent.Property != null && parent.CsType != parent.Property.PropertyType) if (parent.Property != null && parent.CsType != parent.Property.PropertyType)
objval = Utils.GetDataReaderValue(parent.Property.PropertyType, objval); objval = Utils.GetDataReaderValue(parent.Property.PropertyType, objval);
if (objval == DBNull.Value) objval = null;
return objval; return objval;
} }
var ctorParmsLength = 0; var ctorParmsLength = 0;
@ -1116,7 +1117,7 @@ namespace FreeSql.Internal
if (fsql != null) if (fsql != null)
{ {
if (asSelectParentExp != null) if (asSelectParentExp != null)
{ //执行 asSelect() 的关联OneToManyManyToMany { //执行 AsSelect() 的关联OneToManyManyToMany
if (fsqltables[0].Parameter == null) if (fsqltables[0].Parameter == null)
{ {
fsqltables[0].Alias = $"tb_{fsqltables.Count}"; fsqltables[0].Alias = $"tb_{fsqltables.Count}";
@ -1287,15 +1288,30 @@ namespace FreeSql.Internal
case "ToOne": case "ToOne":
case "First": case "First":
var tscClone2 = tsc.CloneDisableDiyParse(); var tscClone2 = tsc.CloneDisableDiyParse();
tscClone2.subSelect001 = fsql as Select0Provider; //#405 Oracle within group(order by ..) var fsqlSelect0p = fsql as Select0Provider;
tscClone2.subSelect001 = fsqlSelect0p; //#405 Oracle within group(order by ..)
tscClone2.isDisableDiyParse = false; tscClone2.isDisableDiyParse = false;
tscClone2._tables = fsqltables; tscClone2._tables = fsqltables;
var exp3Args02 = (exp3.Arguments.FirstOrDefault() as UnaryExpression)?.Operand as LambdaExpression; var exp3Args02 = (exp3.Arguments.FirstOrDefault() as UnaryExpression)?.Operand as LambdaExpression;
if (exp3Args02.Parameters.Count == 1 && exp3Args02.Parameters[0].Type.FullName.StartsWith("FreeSql.Internal.Model.HzyTuple`")) if (exp3Args02.Parameters.Count == 1 && exp3Args02.Parameters[0].Type.FullName.StartsWith("FreeSql.Internal.Model.HzyTuple`"))
exp3Args02 = new ReplaceHzyTupleToMultiParam().Modify(exp3Args02, fsqltables); exp3Args02 = new ReplaceHzyTupleToMultiParam().Modify(exp3Args02, fsqltables);
var sqlFirst = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { ExpressionLambdaToSql(exp3Args02, tscClone2) })?.ToString(); var sqlFirstField = ExpressionLambdaToSql(exp3Args02, tscClone2);
var sqlFirst = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { sqlFirstField })?.ToString();
if (string.IsNullOrEmpty(sqlFirst) == false) if (string.IsNullOrEmpty(sqlFirst) == false)
{
if (fsqlSelect0p._limit > 0)
{
switch (_ado.DataType) //使用 Limit 后的 IN 子查询需要套一层
{
case DataType.MySql:
case DataType.OdbcMySql:
if (exp3.Method.Name == "ToList")
return $"( SELECT * FROM ({sqlFirst.Replace(" \r\n", " \r\n ")}) ftblmt50 )";
break;
}
}
return $"({sqlFirst.Replace(" \r\n", " \r\n ")})"; return $"({sqlFirst.Replace(" \r\n", " \r\n ")})";
}
break; break;
} }
} }

View File

@ -557,7 +557,7 @@ namespace FreeSql.Internal.CommonProvider
public void ExecuteReader(Action<FetchCallbackArgs<DbDataReader>> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, null, fetchHandler, cmdType, cmdText, 0, cmdParms); public void ExecuteReader(Action<FetchCallbackArgs<DbDataReader>> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, null, fetchHandler, cmdType, cmdText, 0, cmdParms);
public void ExecuteReader(DbTransaction transaction, Action<FetchCallbackArgs<DbDataReader>> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, transaction, fetchHandler, cmdType, cmdText, 0, cmdParms); public void ExecuteReader(DbTransaction transaction, Action<FetchCallbackArgs<DbDataReader>> fetchHandler, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, transaction, fetchHandler, cmdType, cmdText, 0, cmdParms);
public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action<FetchCallbackArgs<DbDataReader>> fetchHandler, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) => ExecuteReaderMultiple(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdTimeout, cmdParms); public void ExecuteReader(DbConnection connection, DbTransaction transaction, Action<FetchCallbackArgs<DbDataReader>> fetchHandler, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) => ExecuteReaderMultiple(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdTimeout, cmdParms);
void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransaction transaction, Action<FetchCallbackArgs<DbDataReader>, int> fetchHandler, Action<DbDataReader, int> schemaHandler, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms) public void ExecuteReaderMultiple(int multipleResult, DbConnection connection, DbTransaction transaction, Action<FetchCallbackArgs<DbDataReader>, int> fetchHandler, Action<DbDataReader, int> schemaHandler, CommandType cmdType, string cmdText, int cmdTimeout, params DbParameter[] cmdParms)
{ {
if (string.IsNullOrEmpty(cmdText)) return; if (string.IsNullOrEmpty(cmdText)) return;
var dt = DateTime.Now; var dt = DateTime.Now;

View File

@ -476,7 +476,7 @@ namespace FreeSql.Internal.CommonProvider
public Task ExecuteReaderAsync(Func<FetchCallbackArgs<DbDataReader>, Task> fetchHandler, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderAsync(null, null, fetchHandler, cmdType, cmdText, 0, cmdParms, cancellationToken); public Task ExecuteReaderAsync(Func<FetchCallbackArgs<DbDataReader>, Task> fetchHandler, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderAsync(null, null, fetchHandler, cmdType, cmdText, 0, cmdParms, cancellationToken);
public Task ExecuteReaderAsync(DbTransaction transaction, Func<FetchCallbackArgs<DbDataReader>, Task> fetchHandler, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderAsync(null, transaction, fetchHandler, cmdType, cmdText, 0, cmdParms, cancellationToken); public Task ExecuteReaderAsync(DbTransaction transaction, Func<FetchCallbackArgs<DbDataReader>, Task> fetchHandler, CommandType cmdType, string cmdText, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderAsync(null, transaction, fetchHandler, cmdType, cmdText, 0, cmdParms, cancellationToken);
public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func<FetchCallbackArgs<DbDataReader>, Task> fetchHandler, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderMultipleAsync(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken); public Task ExecuteReaderAsync(DbConnection connection, DbTransaction transaction, Func<FetchCallbackArgs<DbDataReader>, Task> fetchHandler, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) => ExecuteReaderMultipleAsync(1, connection, transaction, (fetch, result) => fetchHandler(fetch), null, cmdType, cmdText, cmdTimeout, cmdParms, cancellationToken);
async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func<FetchCallbackArgs<DbDataReader>, int, Task> fetchHandler, Action<DbDataReader, int> schemaHandler, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default) public async Task ExecuteReaderMultipleAsync(int multipleResult, DbConnection connection, DbTransaction transaction, Func<FetchCallbackArgs<DbDataReader>, int, Task> fetchHandler, Action<DbDataReader, int> schemaHandler, CommandType cmdType, string cmdText, int cmdTimeout, DbParameter[] cmdParms, CancellationToken cancellationToken = default)
{ {
if (string.IsNullOrEmpty(cmdText)) return; if (string.IsNullOrEmpty(cmdText)) return;
var dt = DateTime.Now; var dt = DateTime.Now;

View File

@ -128,7 +128,7 @@ namespace FreeSql.Internal.CommonProvider
} }
} }
public virtual int ExecuteDDLStatements(string ddl) => _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl); public virtual int ExecuteDDLStatements(string ddl) => string.IsNullOrWhiteSpace(ddl) ? 0 : _orm.Ado.ExecuteNonQuery(CommandType.Text, ddl);
public static string ReplaceIndexName(string indexName, string tbname) => string.IsNullOrEmpty(indexName) ? indexName : Regex.Replace(indexName, @"\{\s*TableName\s*\}", tbname, RegexOptions.IgnoreCase); public static string ReplaceIndexName(string indexName, string tbname) => string.IsNullOrEmpty(indexName) ? indexName : Regex.Replace(indexName, @"\{\s*TableName\s*\}", tbname, RegexOptions.IgnoreCase);
} }

View File

@ -702,7 +702,7 @@ namespace FreeSql.Internal.CommonProvider
{ {
case DataType.MySql: case DataType.MySql:
case DataType.OdbcMySql: case DataType.OdbcMySql:
_tosqlAppendContent = " for update"; _tosqlAppendContent = $"{_tosqlAppendContent} for update";
break; break;
case DataType.SqlServer: case DataType.SqlServer:
case DataType.OdbcSqlServer: case DataType.OdbcSqlServer:
@ -712,21 +712,21 @@ namespace FreeSql.Internal.CommonProvider
case DataType.OdbcPostgreSQL: case DataType.OdbcPostgreSQL:
case DataType.KingbaseES: case DataType.KingbaseES:
case DataType.OdbcKingbaseES: case DataType.OdbcKingbaseES:
_tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}"; _tosqlAppendContent = $"{_tosqlAppendContent} for update{(noawait ? " nowait" : "")}";
break; break;
case DataType.Oracle: case DataType.Oracle:
case DataType.OdbcOracle: case DataType.OdbcOracle:
case DataType.Dameng: case DataType.Dameng:
case DataType.OdbcDameng: case DataType.OdbcDameng:
_tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}"; _tosqlAppendContent = $"{_tosqlAppendContent} for update{(noawait ? " nowait" : "")}";
break; break;
case DataType.Sqlite: case DataType.Sqlite:
break; break;
case DataType.ShenTong: //神通测试中发现,不支持 nowait case DataType.ShenTong: //神通测试中发现,不支持 nowait
_tosqlAppendContent = " for update"; _tosqlAppendContent = $"{_tosqlAppendContent} for update";
break; break;
case DataType.Firebird: case DataType.Firebird:
_tosqlAppendContent = " for update with lock"; _tosqlAppendContent = $"{_tosqlAppendContent} for update with lock";
break; break;
} }
return this as TSelect; return this as TSelect;

View File

@ -1348,7 +1348,12 @@ namespace FreeSql.Internal
orm.Aop.AuditDataReaderHandler(orm, args); orm.Aop.AuditDataReaderHandler(orm, args);
return args.Value; return args.Value;
} }
if (orm.Ado.DataType == DataType.Dameng && dr.IsDBNull(index)) return null; //OdbcDameng 不会报错 switch (orm.Ado.DataType)
{
case DataType.Dameng: //OdbcDameng 不会报错
if (dr.IsDBNull(index)) return null;
break;
}
return dr.GetValue(index); return dr.GetValue(index);
} }
internal static RowInfo ExecuteArrayRowReadClassOrTuple(string flagStr, Type typeOrg, int[] indexes, DbDataReader row, int dataIndex, CommonUtils _commonUtils) internal static RowInfo ExecuteArrayRowReadClassOrTuple(string flagStr, Type typeOrg, int[] indexes, DbDataReader row, int dataIndex, CommonUtils _commonUtils)

View File

@ -471,7 +471,6 @@ namespace FreeSql.MsAccess
var scripts = ddl.Split(new string[] { ";\r\n" }, StringSplitOptions.None).Where(a => string.IsNullOrEmpty(a.Trim()) == false).ToArray(); var scripts = ddl.Split(new string[] { ";\r\n" }, StringSplitOptions.None).Where(a => string.IsNullOrEmpty(a.Trim()) == false).ToArray();
if (scripts.Any() == false) return 0; if (scripts.Any() == false) return 0;
if (scripts.Length == 1) return base.ExecuteDDLStatements(ddl);
var affrows = 0; var affrows = 0;
foreach (var script in scripts) foreach (var script in scripts)

View File

@ -399,7 +399,6 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI
var scripts = ddl.Split(new string[] { ";\r\n" }, StringSplitOptions.None).Where(a => string.IsNullOrEmpty(a.Trim()) == false).ToArray(); var scripts = ddl.Split(new string[] { ";\r\n" }, StringSplitOptions.None).Where(a => string.IsNullOrEmpty(a.Trim()) == false).ToArray();
if (scripts.Any() == false) return 0; if (scripts.Any() == false) return 0;
if (scripts.Length == 1) return base.ExecuteDDLStatements(ddl);
var affrows = 0; var affrows = 0;
foreach (var script in scripts) foreach (var script in scripts)

View File

@ -1,13 +1,13 @@
using FreeSql.Internal; using FreeSql.Internal;
using FreeSql.Internal.CommonProvider; using FreeSql.Internal.CommonProvider;
using FreeSql.PostgreSQL.Curd; using FreeSql.PostgreSQL.Curd;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Npgsql.LegacyPostgis; using Npgsql.LegacyPostgis;
using NpgsqlTypes; using NpgsqlTypes;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data;
using System.Data.Common; using System.Data.Common;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Net; using System.Net;
@ -63,19 +63,39 @@ namespace FreeSql.PostgreSQL
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JObject)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JObject)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JArray)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JArray)] = true;
var MethodJTokenFromObject = typeof(JToken).GetMethod("FromObject", new[] { typeof(object) });
var MethodJObjectFromObject = typeof(JObject).GetMethod("FromObject", new[] { typeof(object) });
var MethodJArrayFromObject = typeof(JArray).GetMethod("FromObject", new[] { typeof(object) });
var MethodJTokenParse = typeof(JToken).GetMethod("Parse", new[] { typeof(string) }); var MethodJTokenParse = typeof(JToken).GetMethod("Parse", new[] { typeof(string) });
var MethodJObjectParse = typeof(JObject).GetMethod("Parse", new[] { typeof(string) }); var MethodJObjectParse = typeof(JObject).GetMethod("Parse", new[] { typeof(string) });
var MethodJArrayParse = typeof(JArray).GetMethod("Parse", new[] { typeof(string) }); var MethodJArrayParse = typeof(JArray).GetMethod("Parse", new[] { typeof(string) });
var MethodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) });
Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) => Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) =>
{ {
switch (type.FullName) switch (type.FullName)
{ {
case "Newtonsoft.Json.Linq.JToken": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJTokenParse, Expression.Convert(valueExp, typeof(string))), typeof(JToken))); case "Newtonsoft.Json.Linq.JToken":
case "Newtonsoft.Json.Linq.JObject": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectParse, Expression.Convert(valueExp, typeof(string))), typeof(JObject))); return Expression.IfThenElse(
case "Newtonsoft.Json.Linq.JArray": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJArrayParse, Expression.Convert(valueExp, typeof(string))), typeof(JArray))); Expression.TypeIs(valueExp, typeof(string)),
case "Npgsql.LegacyPostgis.PostgisGeometry": return Expression.Return(returnTarget, valueExp); Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJTokenParse, Expression.Convert(valueExp, typeof(string))), typeof(JToken))),
case "NetTopologySuite.Geometries.Geometry": return Expression.Return(returnTarget, valueExp); Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJTokenFromObject, valueExp), typeof(JToken))));
case "Newtonsoft.Json.Linq.JObject":
return Expression.IfThenElse(
Expression.TypeIs(valueExp, typeof(string)),
Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectParse, Expression.Convert(valueExp, typeof(string))), typeof(JObject))),
Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectFromObject, valueExp), typeof(JObject))));
case "Newtonsoft.Json.Linq.JArray":
return Expression.IfThenElse(
Expression.TypeIs(valueExp, typeof(string)),
Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJArrayParse, Expression.Convert(valueExp, typeof(string))), typeof(JArray))),
Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJArrayFromObject, valueExp), typeof(JArray))));
case "Npgsql.LegacyPostgis.PostgisGeometry":
return Expression.Return(returnTarget, valueExp);
case "NetTopologySuite.Geometries.Geometry":
return Expression.Return(returnTarget, valueExp);
} }
if (typeof(IList).IsAssignableFrom(type))
return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJsonConvertDeserializeObject, Expression.Convert(valueExp, typeof(string)), Expression.Constant(type, typeof(Type))), type));
return null; return null;
}); });
} }