From 704bb5fc6b96497963d9fc2b4038722ac244aa01 Mon Sep 17 00:00:00 2001 From: d4ilys <963922242@qq.com> Date: Thu, 16 Oct 2025 09:49:34 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E4=BC=98=E5=8C=96QuestDb=20IHttpClientFact?= =?UTF-8?q?ory=E5=8F=8AIServiceCollection=E7=9B=B8=E5=85=B3=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTest.cs b/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTest.cs index a1fb83c80..287cdda5f 100644 --- a/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTest.cs @@ -21,7 +21,7 @@ namespace FreeSql.Tests.QuestDb .UseConnectionString(FreeSql.DataType.QuestDb, @"host=192.168.1.114;port=8812;username=admin;password=quest;database=qdb;ServerCompatibilityMode=NoTypeLoading;") .UseMonitorCommand(cmd => Debug.WriteLine($"Sql:{cmd.CommandText}")) //监听SQL语句 - .UseQuestDbRestAPI("192.168.1.114:9000") + .UseQuestDbRestAPI("192.168.1.114:9000") .Build(); } From 3b10c5f42868d6251a21b8d47ac784af6a9d5f29 Mon Sep 17 00:00:00 2001 From: d4ilys <963922242@qq.com> Date: Thu, 16 Oct 2025 09:49:57 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E4=BC=98=E5=8C=96QuestDb=20IHttpClientFact?= =?UTF-8?q?ory=E5=8F=8AIServiceCollection=E7=9B=B8=E5=85=B3=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../QuestDbGlobalExtensions.cs | 143 ++++++++++-------- .../QuestDbProvider.cs | 4 - ...uestDbContainer.cs => ServiceContainer.cs} | 12 +- 3 files changed, 89 insertions(+), 70 deletions(-) rename Providers/FreeSql.Provider.QuestDb/{QuestDbContainer.cs => ServiceContainer.cs} (62%) diff --git a/Providers/FreeSql.Provider.QuestDb/QuestDbGlobalExtensions.cs b/Providers/FreeSql.Provider.QuestDb/QuestDbGlobalExtensions.cs index a047356a0..4d0a20efe 100644 --- a/Providers/FreeSql.Provider.QuestDb/QuestDbGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.QuestDb/QuestDbGlobalExtensions.cs @@ -21,6 +21,7 @@ using System.Threading.Tasks; using System.Web; using FreeSql.Provider.QuestDb; using System.Net; +using Microsoft.Extensions.DependencyInjection; public static partial class QuestDbGlobalExtensions { @@ -35,8 +36,51 @@ public static partial class QuestDbGlobalExtensions private static readonly QuestDbAdo _questDbAdo = new QuestDbAdo(); - public static FreeSqlBuilder UseQuestDbRestAPI(this FreeSqlBuilder build, string host, string username = "", - string password = "") => RestAPIExtension.UseQuestDbRestAPI(build, host, username, password); + /// + /// 启动QuestDb Http功能 + /// + /// + /// + /// + /// + /// + public static FreeSqlBuilder UseQuestDbRestAPI(this FreeSqlBuilder builder, string host, string username = "", + string password = "") + { + //初始化容器,添加HttpClient + ServiceContainer.Initialize(service => + { + service.AddHttpClient("QuestDb", client => client.BaseAddress = new Uri(host)) + .ConfigurePrimaryHttpMessageHandler(handlerBuilder => + { + //忽略SSL验证 + return new HttpClientHandler + { + ClientCertificateOptions = ClientCertificateOption.Manual, + ServerCertificateCustomValidationCallback = + (httpRequestMessage, cert, certChain, policyErrors) => true + }; + }); + + var description = new QuestResetApiFeatures() + { + BaseAddress = host + }; + + if (!string.IsNullOrWhiteSpace(username) && !string.IsNullOrWhiteSpace(password)) + { + var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}")); + description.BasicToken = $"Basic {base64}"; + } + + service.AddSingleton(description); + }); + + //RestApi需要无参数 + builder.UseNoneCommandParameter(true); + + return builder; + } /// /// 对于多个时间序列存储在同一个表中的场景,根据时间戳检索给定键或键组合的最新项。 @@ -50,7 +94,7 @@ public static partial class QuestDbGlobalExtensions public static ISelect LatestOn(this ISelect select, Expression> timestamp, Expression> partition) { - LatestOnExtension.InternelImpl(timestamp, partition); + LatestOnExtension.InternalImpl(timestamp, partition); return select; } @@ -67,7 +111,7 @@ public static partial class QuestDbGlobalExtensions Expression> timestamp, Expression> partition) where T2 : class { - LatestOnExtension.InternelImpl(timestamp, partition); + LatestOnExtension.InternalImpl(timestamp, partition); return select; } @@ -84,7 +128,7 @@ public static partial class QuestDbGlobalExtensions Expression> timestamp, Expression> partition) where T2 : class where T3 : class { - LatestOnExtension.InternelImpl(timestamp, partition); + LatestOnExtension.InternalImpl(timestamp, partition); return select; } @@ -101,7 +145,7 @@ public static partial class QuestDbGlobalExtensions Expression> timestamp, Expression> partition) where T2 : class where T3 : class where T4 : class { - LatestOnExtension.InternelImpl(timestamp, partition); + LatestOnExtension.InternalImpl(timestamp, partition); return select; } @@ -162,19 +206,19 @@ public static partial class QuestDbGlobalExtensions public static async Task ExecuteQuestDbBulkCopyAsync(this IInsert that, string dateFormat = "yyyy/M/d H:mm:ss") where T : class { - //思路:通过提供的RestAPI imp,实现快速复制 - if (string.IsNullOrWhiteSpace(RestAPIExtension.BaseUrl)) + var features = ServiceContainer.GetService(); + + if (string.IsNullOrWhiteSpace(features.BaseAddress)) { throw new Exception( - "BulkCopy功能需要启用RestAPI,启用方式:new FreeSqlBuilder().UseQuestDbRestAPI(\"localhost:9000\", \"username\", \"password\")"); + @"BulkCopy功能需要启用RestAPI,启用方式:new FreeSqlBuilder().UseQuestDbRestAPI(""localhost:9000"", ""username"", ""password"")"); } var result = 0; try { - var client = QuestDbContainer.GetService().CreateClient(); - var boundary = "---------------" + DateTime.Now.Ticks.ToString("x"); + var boundary = $"---------------{DateTime.Now.Ticks:x}"; var list = new List(); var insert = that as QuestDbInsert; var name = insert.InternalTableRuleInvoke(); //获取表名 @@ -199,7 +243,7 @@ public static partial class QuestDbGlobalExtensions } }); var schema = JsonConvert.SerializeObject(list); - using (MemoryStream stream = new MemoryStream()) + using (var stream = new MemoryStream()) { //写入CSV文件 using (var writer = new StreamWriter(stream)) @@ -208,29 +252,27 @@ public static partial class QuestDbGlobalExtensions await csv.WriteRecordsAsync(insert._source); } + var client = features.HttpClient; var httpContent = new MultipartFormDataContent(boundary); - if (!string.IsNullOrWhiteSpace(RestAPIExtension.authorization)) - client.DefaultRequestHeaders.Add("Authorization", RestAPIExtension.authorization); + if (!string.IsNullOrWhiteSpace(features.BasicToken)) + client.DefaultRequestHeaders.Add("Authorization", features.BasicToken); httpContent.Add(new StringContent(schema), "schema"); httpContent.Add(new ByteArrayContent(stream.ToArray()), "data"); - //boundary带双引号 可能导致服务器错误情况 httpContent.Headers.Remove("Content-Type"); httpContent.Headers.TryAddWithoutValidation("Content-Type", - "multipart/form-data; boundary=" + boundary); + $"multipart/form-data; boundary={boundary}"); var httpResponseMessage = - await client.PostAsync($"{RestAPIExtension.BaseUrl}/imp?name={name}", httpContent); + await client.PostAsync($"imp?name={name}", httpContent); var readAsStringAsync = await httpResponseMessage.Content.ReadAsStringAsync(); var splitByLine = SplitByLine(readAsStringAsync); - foreach (var s in splitByLine) + foreach (var strings in from s in splitByLine + where s.Contains("Rows") + select s.Split('|') + into strings + where strings[1].Trim() == "Rows imported" + select strings) { - if (s.Contains("Rows")) - { - var strings = s.Split('|'); - if (strings[1].Trim() == "Rows imported") - { - result = Convert.ToInt32(strings[2].Trim()); - } - } + result = Convert.ToInt32(strings[2].Trim()); } } } @@ -249,7 +291,8 @@ public static partial class QuestDbGlobalExtensions /// /// 导入时,时间格式 默认:yyyy/M/d H:mm:ss /// - public static int ExecuteQuestDbBulkCopy(this IInsert insert, string dateFormat = "yyyy/M/d H:mm:ss") where T : class + public static int ExecuteQuestDbBulkCopy(this IInsert insert, string dateFormat = "yyyy/M/d H:mm:ss") + where T : class { return ExecuteQuestDbBulkCopyAsync(insert, dateFormat).ConfigureAwait(false).GetAwaiter().GetResult(); } @@ -294,7 +337,7 @@ static class LatestOnExtension LatestOnString.Value = string.Empty; } - internal static void InternelImpl(Expression> timestamp, + internal static void InternalImpl(Expression> timestamp, Expression> partition) { IsExistence.Value = true; @@ -308,42 +351,22 @@ static class LatestOnExtension } } -static class RestAPIExtension +class QuestResetApiFeatures { - internal static string BaseUrl = string.Empty; - internal static string authorization = string.Empty; + internal string BaseAddress { get; set; } - internal static async Task ExecAsync(string sql) + internal string BasicToken { get; set; } + + internal HttpClient HttpClient => ServiceContainer.GetService().CreateClient("QuestDb"); + + internal async Task ExecAsync(string sql) { //HTTP GET 执行SQL - var result = string.Empty; - var client = QuestDbContainer.GetService().CreateClient(); - var url = $"{BaseUrl}/exec?query={HttpUtility.UrlEncode(sql)}"; - if (!string.IsNullOrWhiteSpace(authorization)) - client.DefaultRequestHeaders.Add("Authorization", authorization); - var httpResponseMessage = await client.GetAsync(url); - result = await httpResponseMessage.Content.ReadAsStringAsync(); + var url = $"exec?query={HttpUtility.UrlEncode(sql)}"; + if (!string.IsNullOrWhiteSpace(BasicToken)) + HttpClient.DefaultRequestHeaders.Add("Authorization", BasicToken); + var httpResponseMessage = await HttpClient.GetAsync(url); + var result = await httpResponseMessage.Content.ReadAsStringAsync(); return result; } - - internal static FreeSqlBuilder UseQuestDbRestAPI(FreeSqlBuilder buider, string host, string username = "", - string password = "") - { - BaseUrl = host; - if (BaseUrl.EndsWith("/")) - BaseUrl = BaseUrl.Remove(BaseUrl.Length - 1); - - if (!BaseUrl.ToLower().StartsWith("http")) - BaseUrl = $"http://{BaseUrl}"; - //生成TOKEN - if (!string.IsNullOrWhiteSpace(username) && !string.IsNullOrWhiteSpace(password)) - { - var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}")); - authorization = $"Basic {base64}"; - } - - //RestApi需要无参数 - buider.UseNoneCommandParameter(true); - return buider; - } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.QuestDb/QuestDbProvider.cs b/Providers/FreeSql.Provider.QuestDb/QuestDbProvider.cs index f937b8290..31c038006 100644 --- a/Providers/FreeSql.Provider.QuestDb/QuestDbProvider.cs +++ b/Providers/FreeSql.Provider.QuestDb/QuestDbProvider.cs @@ -118,10 +118,6 @@ namespace FreeSql.QuestDb Select0Provider._dicMethodDataReaderGetValue[typeof(Guid)] = typeof(DbDataReader).GetMethod("GetGuid", new Type[] { typeof(int) }); - QuestDbContainer.Initialize(service => - { - service.AddHttpClient(); - }); } } diff --git a/Providers/FreeSql.Provider.QuestDb/QuestDbContainer.cs b/Providers/FreeSql.Provider.QuestDb/ServiceContainer.cs similarity index 62% rename from Providers/FreeSql.Provider.QuestDb/QuestDbContainer.cs rename to Providers/FreeSql.Provider.QuestDb/ServiceContainer.cs index fb678d721..31049dcf3 100644 --- a/Providers/FreeSql.Provider.QuestDb/QuestDbContainer.cs +++ b/Providers/FreeSql.Provider.QuestDb/ServiceContainer.cs @@ -1,21 +1,21 @@ using System; using System.Collections.Generic; +using System.Net.Http; using System.Text; using Microsoft.Extensions.DependencyInjection; namespace FreeSql.Provider.QuestDb { - internal class QuestDbContainer + internal class ServiceContainer { - //作用于HttpClientFatory - private static IServiceCollection Services; + private static IServiceCollection _services; internal static IServiceProvider ServiceProvider { get; private set; } internal static void Initialize(Action service) { - Services = new ServiceCollection(); - service?.Invoke(Services); - ServiceProvider = Services.BuildServiceProvider(); + _services = new ServiceCollection(); + service?.Invoke(_services); + ServiceProvider = _services.BuildServiceProvider(); } internal static T GetService() From 7dec9321f6863782609a6f1e37c87289802b2aad Mon Sep 17 00:00:00 2001 From: d4ilys <963922242@qq.com> Date: Thu, 16 Oct 2025 10:00:39 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E4=BC=98=E5=8C=96QuestDb=20Insert=20Update?= =?UTF-8?q?=20=E7=9B=B8=E5=85=B3=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Curd/QuestDbInsert.cs | 25 +++++--- .../Curd/QuestDbUpdate.cs | 58 ++++++++++++------- .../QuestDbGlobalExtensions.cs | 2 +- .../ServiceContainer.cs | 6 +- 4 files changed, 56 insertions(+), 35 deletions(-) diff --git a/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbInsert.cs b/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbInsert.cs index 1087d4a16..c6b52e4cf 100644 --- a/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbInsert.cs +++ b/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbInsert.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using FreeSql.Provider.QuestDb; namespace FreeSql.QuestDb.Curd { @@ -32,11 +33,12 @@ namespace FreeSql.QuestDb.Curd internal void InternalClearData() => ClearData(); internal string InternalTableRuleInvoke() => TableRuleInvoke(); - private int InternelExecuteAffrows() + private int RestApiExecuteAffrows() { //如果设置了RestAPI的Url则走HTTP + var apiFeatures = ServiceContainer.GetService(); var sql = ToSql(); - var execAsync = RestAPIExtension.ExecAsync(sql).GetAwaiter().GetResult(); + var execAsync = apiFeatures.ExecAsync(sql).GetAwaiter().GetResult(); var resultHash = new Hashtable(); try { @@ -49,18 +51,21 @@ namespace FreeSql.QuestDb.Curd throw new Exception("请确认new FreeSqlBuilder().UseQuestDbRestAPI()中设置的用户名密码是否正确."); } } + var ddl = resultHash["ddl"]?.ToString(); return ddl?.ToLower() == "ok" ? 1 : 0; } public override int ExecuteAffrows() { - if (string.IsNullOrWhiteSpace(RestAPIExtension.BaseUrl)) + var apiFeatures = ServiceContainer.GetService(); + if (apiFeatures != null && string.IsNullOrWhiteSpace(apiFeatures.BaseAddress)) { return base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); } - return InternelExecuteAffrows(); + + return RestApiExecuteAffrows(); } public override long ExecuteIdentity() => base.SplitExecuteIdentity( @@ -170,14 +175,16 @@ namespace FreeSql.QuestDb.Curd #else public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { - if (string.IsNullOrWhiteSpace(RestAPIExtension.BaseUrl)) + var apiFeatures = ServiceContainer.GetService(); + if (apiFeatures != null && string.IsNullOrWhiteSpace(apiFeatures.BaseAddress)) { return base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); } - return Task.FromResult(InternelExecuteAffrows()); + + return Task.FromResult(RestApiExecuteAffrows()); } - + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, @@ -187,7 +194,7 @@ namespace FreeSql.QuestDb.Curd base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); - async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) + protected override async Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; @@ -243,7 +250,7 @@ namespace FreeSql.QuestDb.Curd return ret; } - async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) + protected override async Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); diff --git a/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbUpdate.cs b/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbUpdate.cs index 3dae955fc..eeff51ce5 100644 --- a/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbUpdate.cs +++ b/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbUpdate.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using FreeSql.Provider.QuestDb; namespace FreeSql.QuestDb.Curd { @@ -31,10 +32,11 @@ namespace FreeSql.QuestDb.Curd internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col); - private int InternelExecuteAffrows() + private int RestApiExecuteAffrows() { + var apiFeatures = ServiceContainer.GetService(); var sql = ToSql(); - var execAsync = RestAPIExtension.ExecAsync(sql).GetAwaiter().GetResult(); + var execAsync = apiFeatures.ExecAsync(sql).GetAwaiter().GetResult(); var resultHash = new Hashtable(); try { @@ -47,6 +49,7 @@ namespace FreeSql.QuestDb.Curd throw new Exception("请确认new FreeSqlBuilder().UseQuestDbRestAPI()中设置的用户名密码是否正确."); } } + var ddl = resultHash["ddl"]?.ToString(); var updated = Convert.ToInt32(resultHash["updated"]); return ddl?.ToLower() == "ok" ? updated : 0; @@ -54,19 +57,23 @@ namespace FreeSql.QuestDb.Curd public override int ExecuteAffrows() { - //如果设置了RestAPI中Url则走HTTP - if (string.IsNullOrWhiteSpace(RestAPIExtension.BaseUrl)) + //如果设置了RestApi 则走HTTP执行Sql + var apiFeatures = ServiceContainer.GetService(); + if (apiFeatures != null && string.IsNullOrWhiteSpace(apiFeatures.BaseAddress)) { return base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); } - return InternelExecuteAffrows(); + + return RestApiExecuteAffrows(); } - protected override List ExecuteUpdated(IEnumerable columns) => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, columns); + protected override List ExecuteUpdated(IEnumerable columns) => + base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, + _batchParameterLimit > 0 ? _batchParameterLimit : 3000, columns); - protected override List RawExecuteUpdated(IEnumerable columns) - { + protected override List RawExecuteUpdated(IEnumerable columns) + { var ret = new List(); DbParameter[] dbParms = null; StringBuilder sbret = null; @@ -94,10 +101,11 @@ namespace FreeSql.QuestDb.Curd Exception exception = null; try - { - var queryType = typeof(TReturn) == typeof(T1) ? (_table.TypeLazy ?? _table.Type) : null; - var rettmp = _orm.Ado.Query(queryType, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); - ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + { + var queryType = typeof(TReturn) == typeof(T1) ? (_table.TypeLazy ?? _table.Type) : null; + var rettmp = _orm.Ado.Query(queryType, _connection, _transaction, CommandType.Text, sql, + _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); ret.AddRange(rettmp); } catch (Exception ex) @@ -178,20 +186,25 @@ namespace FreeSql.QuestDb.Curd #else public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { - if (string.IsNullOrWhiteSpace(RestAPIExtension.BaseUrl)) + var apiFeatures = ServiceContainer.GetService(); + if (apiFeatures != null && string.IsNullOrWhiteSpace(apiFeatures.BaseAddress)) { return base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); } - - return Task.FromResult(InternelExecuteAffrows()); + + return Task.FromResult(RestApiExecuteAffrows()); } - protected override Task> ExecuteUpdatedAsync(IEnumerable columns, CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, columns, cancellationToken); + protected override Task> ExecuteUpdatedAsync(IEnumerable columns, + CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync( + _batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, + columns, cancellationToken); - async protected override Task> RawExecuteUpdatedAsync(IEnumerable columns, CancellationToken cancellationToken = default) - { + protected override async Task> RawExecuteUpdatedAsync(IEnumerable columns, + CancellationToken cancellationToken = default) + { var ret = new List(); DbParameter[] dbParms = null; StringBuilder sbret = null; @@ -219,10 +232,11 @@ namespace FreeSql.QuestDb.Curd Exception exception = null; try - { - var queryType = typeof(TReturn) == typeof(T1) ? (_table.TypeLazy ?? _table.Type) : null; - var rettmp = await _orm.Ado.QueryAsync(queryType, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + { + var queryType = typeof(TReturn) == typeof(T1) ? (_table.TypeLazy ?? _table.Type) : null; + var rettmp = await _orm.Ado.QueryAsync(queryType, _connection, _transaction, + CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); ret.AddRange(rettmp); } catch (Exception ex) diff --git a/Providers/FreeSql.Provider.QuestDb/QuestDbGlobalExtensions.cs b/Providers/FreeSql.Provider.QuestDb/QuestDbGlobalExtensions.cs index 4d0a20efe..aff85f716 100644 --- a/Providers/FreeSql.Provider.QuestDb/QuestDbGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.QuestDb/QuestDbGlobalExtensions.cs @@ -351,7 +351,7 @@ static class LatestOnExtension } } -class QuestResetApiFeatures +internal class QuestResetApiFeatures { internal string BaseAddress { get; set; } diff --git a/Providers/FreeSql.Provider.QuestDb/ServiceContainer.cs b/Providers/FreeSql.Provider.QuestDb/ServiceContainer.cs index 31049dcf3..628dd7faf 100644 --- a/Providers/FreeSql.Provider.QuestDb/ServiceContainer.cs +++ b/Providers/FreeSql.Provider.QuestDb/ServiceContainer.cs @@ -9,18 +9,18 @@ namespace FreeSql.Provider.QuestDb internal class ServiceContainer { private static IServiceCollection _services; - internal static IServiceProvider ServiceProvider { get; private set; } + private static IServiceProvider _serviceProvider; internal static void Initialize(Action service) { _services = new ServiceCollection(); service?.Invoke(_services); - ServiceProvider = _services.BuildServiceProvider(); + _serviceProvider = _services.BuildServiceProvider(); } internal static T GetService() { - return ServiceProvider.GetService(); + return _serviceProvider == null ? default : _serviceProvider.GetService(); } } } \ No newline at end of file From 7e4d248dafb4a19de9cf727469966013596457a8 Mon Sep 17 00:00:00 2001 From: d4ilys <963922242@qq.com> Date: Thu, 16 Oct 2025 11:22:26 +0800 Subject: [PATCH 4/5] =?UTF-8?q?QuestDb=20=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Crud/QuestDbTestInsertAndUpdate.cs | 31 ++++++++++--------- .../Crud/QuestDbTestSelect.cs | 23 +++++++------- .../Crud/QuestDbTestUpdate.cs | 16 +++++----- .../FreeSql.Tests.Provider.QuestDb.csproj | 26 ++++++++++++++++ .../QuestDbCodeFirstTest.cs | 12 +++---- .../QuestDbDbFirstTest.cs | 4 +-- .../QuestDbIssue/QuestDbIssue.cs | 12 +++---- .../QuestDbTest.cs | 10 +++--- .../QuestDb_Model_SelectTest.cs | 0 .../QuestDbTestModel/QuestDb_Model_Test01.cs | 0 .../QuestDbTestModel/QuestDb_Model_Type01.cs | 0 .../Utils/OrderAttribute.cs | 0 .../Utils/TestOrders.cs | 0 13 files changed, 80 insertions(+), 54 deletions(-) rename FreeSql.Tests/{FreeSql.Tests/QuestDb => FreeSql.Tests.Provider.QuestDb}/Crud/QuestDbTestInsertAndUpdate.cs (89%) rename FreeSql.Tests/{FreeSql.Tests/QuestDb => FreeSql.Tests.Provider.QuestDb}/Crud/QuestDbTestSelect.cs (88%) rename FreeSql.Tests/{FreeSql.Tests/QuestDb => FreeSql.Tests.Provider.QuestDb}/Crud/QuestDbTestUpdate.cs (84%) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/FreeSql.Tests.Provider.QuestDb.csproj rename FreeSql.Tests/{FreeSql.Tests/QuestDb => FreeSql.Tests.Provider.QuestDb}/QuestDbCodeFirstTest.cs (70%) rename FreeSql.Tests/{FreeSql.Tests/QuestDb => FreeSql.Tests.Provider.QuestDb}/QuestDbDbFirstTest.cs (75%) rename FreeSql.Tests/{FreeSql.Tests/QuestDb => FreeSql.Tests.Provider.QuestDb}/QuestDbIssue/QuestDbIssue.cs (83%) rename FreeSql.Tests/{FreeSql.Tests/QuestDb => FreeSql.Tests.Provider.QuestDb}/QuestDbTest.cs (58%) rename FreeSql.Tests/{FreeSql.Tests/QuestDb => FreeSql.Tests.Provider.QuestDb}/QuestDbTestModel/QuestDb_Model_SelectTest.cs (100%) rename FreeSql.Tests/{FreeSql.Tests/QuestDb => FreeSql.Tests.Provider.QuestDb}/QuestDbTestModel/QuestDb_Model_Test01.cs (100%) rename FreeSql.Tests/{FreeSql.Tests/QuestDb => FreeSql.Tests.Provider.QuestDb}/QuestDbTestModel/QuestDb_Model_Type01.cs (100%) rename FreeSql.Tests/{FreeSql.Tests/QuestDb => FreeSql.Tests.Provider.QuestDb}/Utils/OrderAttribute.cs (100%) rename FreeSql.Tests/{FreeSql.Tests/QuestDb => FreeSql.Tests.Provider.QuestDb}/Utils/TestOrders.cs (100%) diff --git a/FreeSql.Tests/FreeSql.Tests/QuestDb/Crud/QuestDbTestInsertAndUpdate.cs b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/Crud/QuestDbTestInsertAndUpdate.cs similarity index 89% rename from FreeSql.Tests/FreeSql.Tests/QuestDb/Crud/QuestDbTestInsertAndUpdate.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/Crud/QuestDbTestInsertAndUpdate.cs index 15cebad3e..42f8a014d 100644 --- a/FreeSql.Tests/FreeSql.Tests/QuestDb/Crud/QuestDbTestInsertAndUpdate.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/Crud/QuestDbTestInsertAndUpdate.cs @@ -17,7 +17,7 @@ namespace FreeSql.Tests.QuestDb.Crud [Fact,Order(1)] public async Task TestInsertAsync() { - var result = await fsql.Insert(new QuestDb_Model_Test01() + var result = await Db.Insert(new QuestDb_Model_Test01() { Primarys = Guid.NewGuid().ToString(), CreateTime = DateTime.Now, @@ -66,7 +66,7 @@ namespace FreeSql.Tests.QuestDb.Crud NameUpdate = "NameUpdate" }, }; - var result = await fsql.Insert(list).ExecuteAffrowsAsync(); + var result = await Db.Insert(list).ExecuteAffrowsAsync(); Assert.True(result > 0); } @@ -106,14 +106,14 @@ namespace FreeSql.Tests.QuestDb.Crud NameUpdate = "NameUpdate" }, }; - var result = await fsql.Insert(list).IgnoreColumns(q => q.NameInsert).ExecuteAffrowsAsync(); + var result = await Db.Insert(list).IgnoreColumns(q => q.NameInsert).ExecuteAffrowsAsync(); Assert.True(result > 0); } [Fact] public async Task TestRestInsertAsync() { - var result = await restFsql.Insert(new QuestDb_Model_Test01() + var result = await RestApiDb.Insert(new QuestDb_Model_Test01() { Primarys = Guid.NewGuid().ToString(), CreateTime = DateTime.Now, @@ -162,7 +162,7 @@ namespace FreeSql.Tests.QuestDb.Crud NameUpdate = "NameUpdate" }, }; - var result = await restFsql.Insert(list).ExecuteAffrowsAsync(); + var result = await RestApiDb.Insert(list).ExecuteAffrowsAsync(); Assert.True(result > 0); } @@ -202,7 +202,7 @@ namespace FreeSql.Tests.QuestDb.Crud NameUpdate = "NameUpdate" }, }; - var result = await restFsql.Insert(list).IgnoreColumns(q => q.NameInsert).ExecuteAffrowsAsync(); + var result = await RestApiDb.Insert(list).IgnoreColumns(q => q.NameInsert).ExecuteAffrowsAsync(); Assert.True(result > 0); } @@ -224,7 +224,7 @@ namespace FreeSql.Tests.QuestDb.Crud }); } - var result = await restFsql.Insert(list).ExecuteQuestDbBulkCopyAsync(); + var result = await RestApiDb.Insert(list).ExecuteQuestDbBulkCopyAsync(); Assert.True(result > 0); } @@ -233,7 +233,7 @@ namespace FreeSql.Tests.QuestDb.Crud public void TestNormalUpdate() { var updateTime = DateTime.Now; - var updateObj = fsql.Update() + var updateObj = Db.Update() .Set(q => q.NameUpdate, "UpdateNow") // .Set(q => q.CreateTime, DateTime.Now) 分表的时间不可以随便改 .Where(q => q.Id == "1"); @@ -253,7 +253,7 @@ WHERE (""Id"" = '1')"; { var primary = Guid.NewGuid().ToString(); //先插入 - fsql.Insert(new QuestDb_Model_Test01() + Db.Insert(new QuestDb_Model_Test01() { Primarys = primary, CreateTime = DateTime.Now, @@ -269,11 +269,11 @@ WHERE (""Id"" = '1')"; Id = primary, Activos = 12.65, }; - var updateObj = fsql.Update().SetSourceIgnore(updateModel, o => o == null); + var updateObj = Db.Update().SetSourceIgnore(updateModel, o => o == null); var sql = updateObj.ToSql(); Debug.WriteLine(sql); var result = updateObj.ExecuteAffrows(); - var resultAsync = fsql.Update().SetSourceIgnore(updateModel, o => o == null) + var resultAsync = Db.Update().SetSourceIgnore(updateModel, o => o == null) .ExecuteAffrows(); Assert.True(result > 0); Assert.True(resultAsync > 0); @@ -288,7 +288,7 @@ WHERE (""Id"" = '{primary}')", sql); var primary = Guid.NewGuid().ToString(); var updateTime = DateTime.Now; //先插入 - fsql.Insert(new QuestDb_Model_Test01() + Db.Insert(new QuestDb_Model_Test01() { Primarys = primary, CreateTime = DateTime.Now, @@ -298,6 +298,7 @@ WHERE (""Id"" = '{primary}')", sql); NameInsert = "NameInsert", NameUpdate = "NameUpdate" }).ExecuteAffrows(); + var updateModel = new QuestDb_Model_Test01 { Id = primary, @@ -305,12 +306,12 @@ WHERE (""Id"" = '{primary}')", sql); IsCompra = true, CreateTime = DateTime.Now }; - var updateObj = fsql.Update().SetSource(updateModel) + var updateObj = Db.Update().SetSource(updateModel) .IgnoreColumns(q => new { q.Id, q.CreateTime }); var sql = updateObj.ToSql(); Debug.WriteLine(sql); var result = updateObj.ExecuteAffrows(); - var resultAsync = await fsql.Update().SetSource(updateModel) + var resultAsync = await Db.Update().SetSource(updateModel) .IgnoreColumns(q => new { q.Id, q.CreateTime }).ExecuteAffrowsAsync(); Assert.True(result > 0); Assert.True(resultAsync > 0); @@ -323,7 +324,7 @@ WHERE (""Id"" = '{primary}')", sql); public async Task TestUpdateToUpdateAsync() { //官网demo有问题,暂时放弃此功能 - var result = await fsql.Select().Where(q => q.Id == "IdAsync" && q.NameInsert == null) + var result = await Db.Select().Where(q => q.Id == "IdAsync" && q.NameInsert == null) .ToUpdate() .Set(q => q.UpdateTime, DateTime.Now) .ExecuteAffrowsAsync(); diff --git a/FreeSql.Tests/FreeSql.Tests/QuestDb/Crud/QuestDbTestSelect.cs b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/Crud/QuestDbTestSelect.cs similarity index 88% rename from FreeSql.Tests/FreeSql.Tests/QuestDb/Crud/QuestDbTestSelect.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/Crud/QuestDbTestSelect.cs index 62a627f3f..013b988fa 100644 --- a/FreeSql.Tests/FreeSql.Tests/QuestDb/Crud/QuestDbTestSelect.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/Crud/QuestDbTestSelect.cs @@ -6,7 +6,6 @@ using System.Text; using System.Threading.Tasks; using FreeSql.DataAnnotations; using FreeSql.Tests.QuestDb.QuestDbTestModel; -using NetTopologySuite.Operation.Valid; using Xunit; using static FreeSql.Tests.QuestDb.QuestDbTest; @@ -17,13 +16,13 @@ namespace FreeSql.Tests.QuestDb.Crud [Fact] public void TestNormal() { - var sql = fsql.Select().ToSql(); + var sql = Db.Select().ToSql(); Debug.WriteLine(sql); Assert.Equal( @"SELECT a.""Primarys"", a.""Id"", a.""NameUpdate"", a.""NameInsert"", a.""Activos"", a.""CreateTime"", a.""UpdateTime"", a.""IsCompra"" FROM ""QuestDb_Model_Test01"" a", sql); - var sqlWhere = fsql.Select().Where(q => + var sqlWhere = Db.Select().Where(q => q.UpdateTime.Value.BetweenEnd(DateTime.Parse("2023-02-17 09:35:00"), DateTime.Parse("2023-02-17 10:20:00"))).ToSql(); Debug.WriteLine(sqlWhere); @@ -41,7 +40,7 @@ WHERE (a.""UpdateTime"" >= '2023-02-17 09:35:00.000000' and a.""UpdateTime"" < ' public void TestPageAndCount(int page) { var pageSize = 5; - var select = fsql.Select().Count(out var total).Page(page, pageSize); + var select = Db.Select().Count(out var total).Page(page, pageSize); var sql = select.ToSql(); Debug.WriteLine(sql); switch (page) @@ -70,7 +69,7 @@ limit 10,15", sql); [Fact] public void TestNavigation() { - var select = fsql.Select() + var select = Db.Select() .LeftJoin(a => a.Category.Id == a.CategoryId) .LeftJoin(a => a.Category.Parent.Id == a.Category.ParentId) .Where(a => a.Category.Parent.Id > 0); @@ -88,7 +87,7 @@ WHERE (a__Category__Parent.""Id"" > 0)", sql); [Fact] public void TestComplexJoin() { - var select = fsql.Select() + var select = Db.Select() .LeftJoin(w => w.t1.CategoryId == w.t2.Id) .LeftJoin(w => w.t2.ParentId == w.t3.Id) .Where(w => w.t3.Id > 0); @@ -106,10 +105,10 @@ WHERE (c.""Id"" > 0)", sql); [Fact] public void TestUnionAll() { - var select = fsql.Select().Where(a => a.IsCompra == true) + var select = Db.Select().Where(a => a.IsCompra == true) .UnionAll( - fsql.Select().Where(a => a.IsCompra == true), - fsql.Select().Where(a => a.IsCompra == true) + Db.Select().Where(a => a.IsCompra == true), + Db.Select().Where(a => a.IsCompra == true) ) .Where(a => a.IsCompra == true); var sql = select.ToSql(); @@ -134,7 +133,7 @@ WHERE (a.""IsCompra"" = True)", sql); [Fact] public void TestSampleBy() { - var selectSql = fsql.Select() + var selectSql = Db.Select() .SampleBy(1, SampleUnit.day) .WithTempQuery(q => new { q.Id, q.Activos, count = SqlExt.Count(q.Id).ToValue() }) .Where(q => q.Id != "1") @@ -153,7 +152,7 @@ WHERE (a.""Id"" <> '1')"; [Fact] public void TestLatestOn() { - var selectSql = fsql.Select() + var selectSql = Db.Select() .LatestOn(q => q.CreateTime, q => new { q.Id, q.NameUpdate }) .ToSql(); Debug.WriteLine(selectSql); @@ -168,7 +167,7 @@ LATEST ON CreateTime PARTITION BY Id,NameUpdate "; public void TestGroup() { //QUEDTDB的GroupBy PostgrSql有所不同 - var selectSql = fsql.Select() + var selectSql = Db.Select() .WithTempQuery(q => new { q.Id, q.Activos, count = SqlExt.Count(q.Id).ToValue() }) .Where(q => q.Id != "1" && q.count > 1) .ToSql(); diff --git a/FreeSql.Tests/FreeSql.Tests/QuestDb/Crud/QuestDbTestUpdate.cs b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/Crud/QuestDbTestUpdate.cs similarity index 84% rename from FreeSql.Tests/FreeSql.Tests/QuestDb/Crud/QuestDbTestUpdate.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/Crud/QuestDbTestUpdate.cs index edb56d55f..82e7abc4a 100644 --- a/FreeSql.Tests/FreeSql.Tests/QuestDb/Crud/QuestDbTestUpdate.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/Crud/QuestDbTestUpdate.cs @@ -18,7 +18,7 @@ namespace FreeSql.Tests.QuestDb.Crud public void TestNormalRestUpdate() { var updateTime = DateTime.Now; - var updateObj = restFsql.Update() + var updateObj = RestApiDb.Update() .Set(q => q.NameUpdate, "UpdateNow") // .Set(q => q.CreateTime, DateTime.Now) 分表的时间不可以随便改 .Where(q => q.Id == "1"); @@ -38,7 +38,7 @@ WHERE (""Id"" = '1')"; { var primary = Guid.NewGuid().ToString(); //先插入 - restFsql.Insert(new QuestDb_Model_Test01() + RestApiDb.Insert(new QuestDb_Model_Test01() { Primarys = primary, CreateTime = DateTime.Now, @@ -54,11 +54,11 @@ WHERE (""Id"" = '1')"; Id = primary, Activos = 12.65, }; - var updateObj = restFsql.Update().SetSourceIgnore(updateModel, o => o == null); + var updateObj = RestApiDb.Update().SetSourceIgnore(updateModel, o => o == null); var sql = updateObj.ToSql(); Debug.WriteLine(sql); var result = updateObj.ExecuteAffrows(); - var resultAsync = restFsql.Update().SetSourceIgnore(updateModel, o => o == null) + var resultAsync = RestApiDb.Update().SetSourceIgnore(updateModel, o => o == null) .ExecuteAffrows(); Assert.True(result > 0); Assert.True(resultAsync > 0); @@ -73,7 +73,7 @@ WHERE (""Id"" = '{primary}')", sql); var primary = Guid.NewGuid().ToString(); var updateTime = DateTime.Now; //先插入 - restFsql.Insert(new QuestDb_Model_Test01() + RestApiDb.Insert(new QuestDb_Model_Test01() { Primarys = primary, CreateTime = DateTime.Now, @@ -90,12 +90,12 @@ WHERE (""Id"" = '{primary}')", sql); IsCompra = true, CreateTime = DateTime.Now }; - var updateObj = restFsql.Update().SetSource(updateModel) + var updateObj = RestApiDb.Update().SetSource(updateModel) .IgnoreColumns(q => new { q.Id, q.CreateTime }); var sql = updateObj.ToSql(); Debug.WriteLine(sql); var result = updateObj.ExecuteAffrows(); - var resultAsync = await restFsql.Update().SetSource(updateModel) + var resultAsync = await RestApiDb.Update().SetSource(updateModel) .IgnoreColumns(q => new { q.Id, q.CreateTime }).ExecuteAffrowsAsync(); Assert.True(result > 0); Assert.True(resultAsync > 0); @@ -108,7 +108,7 @@ WHERE (""Id"" = '{primary}')", sql); public async Task TestUpdateToUpdateAsync() { //官网demo有问题,暂时放弃此功能 - var result = await restFsql.Select().Where(q => q.Id == "IdAsync" && q.NameInsert == null) + var result = await RestApiDb.Select().Where(q => q.Id == "IdAsync" && q.NameInsert == null) .ToUpdate() .Set(q => q.UpdateTime, DateTime.Now) .ExecuteAffrowsAsync(); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/FreeSql.Tests.Provider.QuestDb.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/FreeSql.Tests.Provider.QuestDb.csproj new file mode 100644 index 000000000..ae8191fe3 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/FreeSql.Tests.Provider.QuestDb.csproj @@ -0,0 +1,26 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbCodeFirstTest.cs similarity index 70% rename from FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbCodeFirstTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbCodeFirstTest.cs index 56e63072c..f0687c29f 100644 --- a/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbCodeFirstTest.cs @@ -16,17 +16,17 @@ namespace FreeSql.Tests.QuestDb [Fact] public void Test_SyncStructure() { - fsql.CodeFirst.SyncStructure(); - fsql.CodeFirst.SyncStructure(typeof(Topic)); - fsql.CodeFirst.SyncStructure(typeof(Category)); - fsql.CodeFirst.SyncStructure(typeof(CategoryType)); + Db.CodeFirst.SyncStructure(); + Db.CodeFirst.SyncStructure(typeof(Topic)); + Db.CodeFirst.SyncStructure(typeof(Category)); + Db.CodeFirst.SyncStructure(typeof(CategoryType)); } [Fact] public void Test_SyncStructure_Type() { - fsql.CodeFirst.SyncStructure(); - var result = fsql.Insert(new QuestDb_Model_Type01() + Db.CodeFirst.SyncStructure(); + var result = Db.Insert(new QuestDb_Model_Type01() { TestBool = false, TestDecimal = (decimal?)153.02, diff --git a/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbDbFirstTest.cs similarity index 75% rename from FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbDbFirstTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbDbFirstTest.cs index 7e2bb11ea..68cc12425 100644 --- a/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbDbFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbDbFirstTest.cs @@ -14,13 +14,13 @@ namespace FreeSql.Tests.QuestDb [Fact] public void Test_ExistsTable() { - var existsTable = QuestDbTest.fsql.DbFirst.ExistsTable(nameof(QuestDb_Model_Test01)); + var existsTable = QuestDbTest.Db.DbFirst.ExistsTable(nameof(QuestDb_Model_Test01)); } [Fact] public void Test_GetTablesByDatabase() { - var tablesByDatabase = QuestDbTest.fsql.DbFirst.GetTablesByDatabase(""); + var tablesByDatabase = QuestDbTest.Db.DbFirst.GetTablesByDatabase(""); tablesByDatabase.ForEach(d => { Debug.WriteLine(d.Name); diff --git a/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbIssue/QuestDbIssue.cs b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbIssue/QuestDbIssue.cs similarity index 83% rename from FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbIssue/QuestDbIssue.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbIssue/QuestDbIssue.cs index 68a0ba0aa..ba56a5ad3 100644 --- a/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbIssue/QuestDbIssue.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbIssue/QuestDbIssue.cs @@ -12,8 +12,8 @@ namespace FreeSql.Tests.QuestDb.QuestDbIssue [Fact] public void Issue1757() { - restFsql.CodeFirst.SyncStructure(); - var count = fsql.Insert(new List() + RestApiDb.CodeFirst.SyncStructure(); + var count = Db.Insert(new List() { new() { @@ -26,15 +26,15 @@ namespace FreeSql.Tests.QuestDb.QuestDbIssue Assert.True(count > 0); - var list = fsql.Select().ToList(); + var list = Db.Select().ToList(); } [Fact] public void Issue1757Many() { - restFsql.CodeFirst.SyncStructure(); - var count = fsql.Insert(new List() + RestApiDb.CodeFirst.SyncStructure(); + var count = Db.Insert(new List() { new() { @@ -61,7 +61,7 @@ namespace FreeSql.Tests.QuestDb.QuestDbIssue Assert.True(count > 0); - var list = fsql.Select().ToList(); + var list = Db.Select().ToList(); } } diff --git a/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbTest.cs similarity index 58% rename from FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbTest.cs index 287cdda5f..64b6dcd73 100644 --- a/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbTest.cs @@ -10,18 +10,18 @@ namespace FreeSql.Tests.QuestDb { public class QuestDbTest { - public static IFreeSql fsql = new FreeSql.FreeSqlBuilder() + public static IFreeSql Db = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.QuestDb, - @"host=192.168.1.114;port=8812;username=admin;password=quest;database=qdb;ServerCompatibilityMode=NoTypeLoading;") + @"host=localhost;port=8812;username=admin;password=quest;database=qdb;ServerCompatibilityMode=NoTypeLoading;") .UseMonitorCommand(cmd => Debug.WriteLine($"Sql:{cmd.CommandText}")) //监听SQL语句 .UseNoneCommandParameter(true) .Build(); - public static IFreeSql restFsql = new FreeSql.FreeSqlBuilder() + public static IFreeSql RestApiDb = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.QuestDb, - @"host=192.168.1.114;port=8812;username=admin;password=quest;database=qdb;ServerCompatibilityMode=NoTypeLoading;") + @"host=localhost;port=8812;username=admin;password=quest;database=qdb;ServerCompatibilityMode=NoTypeLoading;") .UseMonitorCommand(cmd => Debug.WriteLine($"Sql:{cmd.CommandText}")) //监听SQL语句 - .UseQuestDbRestAPI("192.168.1.114:9000") + .UseQuestDbRestAPI("localhost:9000") .Build(); } diff --git a/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTestModel/QuestDb_Model_SelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbTestModel/QuestDb_Model_SelectTest.cs similarity index 100% rename from FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTestModel/QuestDb_Model_SelectTest.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbTestModel/QuestDb_Model_SelectTest.cs diff --git a/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTestModel/QuestDb_Model_Test01.cs b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbTestModel/QuestDb_Model_Test01.cs similarity index 100% rename from FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTestModel/QuestDb_Model_Test01.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbTestModel/QuestDb_Model_Test01.cs diff --git a/FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTestModel/QuestDb_Model_Type01.cs b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbTestModel/QuestDb_Model_Type01.cs similarity index 100% rename from FreeSql.Tests/FreeSql.Tests/QuestDb/QuestDbTestModel/QuestDb_Model_Type01.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/QuestDbTestModel/QuestDb_Model_Type01.cs diff --git a/FreeSql.Tests/FreeSql.Tests/QuestDb/Utils/OrderAttribute.cs b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/Utils/OrderAttribute.cs similarity index 100% rename from FreeSql.Tests/FreeSql.Tests/QuestDb/Utils/OrderAttribute.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/Utils/OrderAttribute.cs diff --git a/FreeSql.Tests/FreeSql.Tests/QuestDb/Utils/TestOrders.cs b/FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/Utils/TestOrders.cs similarity index 100% rename from FreeSql.Tests/FreeSql.Tests/QuestDb/Utils/TestOrders.cs rename to FreeSql.Tests/FreeSql.Tests.Provider.QuestDb/Utils/TestOrders.cs From c4b4fac956ef831bc73a58a02661a91473468438 Mon Sep 17 00:00:00 2001 From: d4ilys <963922242@qq.com> Date: Thu, 16 Oct 2025 11:22:37 +0800 Subject: [PATCH 5/5] =?UTF-8?q?QuestDb=20=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.sln | 18 +- FreeSql/FreeSql.xml | 232 ++++++++---------- .../Curd/QuestDbInsert.cs | 25 +- .../Curd/QuestDbUpdate.cs | 24 +- .../Models/QuestResetApiFeatures.cs | 26 ++ .../Models/RestApiExecResponseJsonBody.cs | 21 ++ .../QuestDbGlobalExtensions.cs | 47 +--- .../ServiceContainer.cs | 2 + 8 files changed, 210 insertions(+), 185 deletions(-) create mode 100644 Providers/FreeSql.Provider.QuestDb/Models/QuestResetApiFeatures.cs create mode 100644 Providers/FreeSql.Provider.QuestDb/Models/RestApiExecResponseJsonBody.cs diff --git a/FreeSql.sln b/FreeSql.sln index 0d10f100e..cf4fc32fd 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -137,6 +137,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.TDen EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.EFModel", "Extensions\FreeSql.Extensions.EFModel\FreeSql.Extensions.EFModel.csproj", "{4281AC48-6FE7-49C3-BE7B-D029058646BC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Tests.Provider.QuestDb", "FreeSql.Tests\FreeSql.Tests.Provider.QuestDb\FreeSql.Tests.Provider.QuestDb.csproj", "{5A59200F-9757-4E0B-B4CF-2E846F25A69A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -831,6 +833,18 @@ Global {4281AC48-6FE7-49C3-BE7B-D029058646BC}.Release|x64.Build.0 = Release|Any CPU {4281AC48-6FE7-49C3-BE7B-D029058646BC}.Release|x86.ActiveCfg = Release|Any CPU {4281AC48-6FE7-49C3-BE7B-D029058646BC}.Release|x86.Build.0 = Release|Any CPU + {5A59200F-9757-4E0B-B4CF-2E846F25A69A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A59200F-9757-4E0B-B4CF-2E846F25A69A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A59200F-9757-4E0B-B4CF-2E846F25A69A}.Debug|x64.ActiveCfg = Debug|Any CPU + {5A59200F-9757-4E0B-B4CF-2E846F25A69A}.Debug|x64.Build.0 = Debug|Any CPU + {5A59200F-9757-4E0B-B4CF-2E846F25A69A}.Debug|x86.ActiveCfg = Debug|Any CPU + {5A59200F-9757-4E0B-B4CF-2E846F25A69A}.Debug|x86.Build.0 = Debug|Any CPU + {5A59200F-9757-4E0B-B4CF-2E846F25A69A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A59200F-9757-4E0B-B4CF-2E846F25A69A}.Release|Any CPU.Build.0 = Release|Any CPU + {5A59200F-9757-4E0B-B4CF-2E846F25A69A}.Release|x64.ActiveCfg = Release|Any CPU + {5A59200F-9757-4E0B-B4CF-2E846F25A69A}.Release|x64.Build.0 = Release|Any CPU + {5A59200F-9757-4E0B-B4CF-2E846F25A69A}.Release|x86.ActiveCfg = Release|Any CPU + {5A59200F-9757-4E0B-B4CF-2E846F25A69A}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -877,8 +891,8 @@ Global {4281AC48-6FE7-49C3-BE7B-D029058646BC} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} - RESX_PrefixTranslations = True RESX_NeutralResourcesLanguage = en-US + RESX_PrefixTranslations = True + SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} EndGlobalSection EndGlobal diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index d62771d4c..79b4f74a8 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1097,6 +1097,93 @@ + + + 动态创建实体类型 + + + + + 配置Class + + 类名 + 类标记的特性[Table(Name = "xxx")] [Index(xxxx)] + + + + + 获取类型构建器,可作为要构建的Type来引用 + + + + + 配置属性 + + 属性名称 + 属性类型 + 属性标记的特性-支持多个 + + + + + 配置属性 + + 属性名称 + 属性类型 + 该属性是否重写父类属性 + 属性标记的特性-支持多个 + + + + + 配置属性 + + 属性名称 + 属性类型 + 该属性是否重写父类属性 + 属性默认值 + 属性标记的特性-支持多个 + + + + + 配置父类 + + 父类类型 + + + + + Override属性 + + + + + + Emit动态创建出Class - Type + + + + + + Emit动态创建出Class - Type,不附带获取TableInfo + + + + + + 首字母小写 + + + + + + + 首字母大写 + + + + 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 "" @@ -5903,6 +5990,28 @@ 对象池 + + + 动态构建Class Type + + + + + + 根据字典,创建 table 对应的实体对象 + + + + + + + + 根据实体对象,创建 table 对应的字典 + + + + + C#: that >= between && that <= and @@ -6510,126 +6619,3 @@ - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: - MySql 5.6+: on duplicate key update - PostgreSQL 9.4+: on conflict do update - SqlServer 2008+: merge into - Oracle 11+: merge into - Sqlite: replace into - DuckDB: on conflict do update - 达梦: merge into - 人大金仓:on conflict do update - 神通:merge into - MsAccess:不支持 - 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 查询数据 - - - - - - - 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 删除数据 - - - - - - - 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步) - v1.5.0 关闭了线程事务超时自动提交的机制 - - 事务体 () => {} - - - - 开启事务(不支持异步) - v1.5.0 关闭了线程事务超时自动提交的机制 - - - 事务体 () => {} - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - diff --git a/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbInsert.cs b/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbInsert.cs index c6b52e4cf..4f6a3b554 100644 --- a/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbInsert.cs +++ b/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbInsert.cs @@ -1,5 +1,7 @@ using FreeSql.Internal; using FreeSql.Internal.Model; +using FreeSql.Provider.QuestDb; +using FreeSql.Provider.QuestDb.Models; using Newtonsoft.Json; using System; using System.Collections; @@ -7,10 +9,10 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq; +using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; -using FreeSql.Provider.QuestDb; namespace FreeSql.QuestDb.Curd { @@ -33,16 +35,16 @@ namespace FreeSql.QuestDb.Curd internal void InternalClearData() => ClearData(); internal string InternalTableRuleInvoke() => TableRuleInvoke(); - private int RestApiExecuteAffrows() + private async Task RestApiExecuteAffrowsAsync() { //如果设置了RestAPI的Url则走HTTP - var apiFeatures = ServiceContainer.GetService(); + var apiFeatures = ServiceContainer.GetService(); var sql = ToSql(); - var execAsync = apiFeatures.ExecAsync(sql).GetAwaiter().GetResult(); - var resultHash = new Hashtable(); + var execAsync = await apiFeatures.ExecAsync(sql); + var result = new RestApiExecResponseJsonBody(); try { - resultHash = JsonConvert.DeserializeObject(execAsync); + result = JsonConvert.DeserializeObject(execAsync); } catch { @@ -52,20 +54,19 @@ namespace FreeSql.QuestDb.Curd } } - var ddl = resultHash["ddl"]?.ToString(); - return ddl?.ToLower() == "ok" ? 1 : 0; + return result.IsSuccessful ? 1 : 0; } public override int ExecuteAffrows() { var apiFeatures = ServiceContainer.GetService(); - if (apiFeatures != null && string.IsNullOrWhiteSpace(apiFeatures.BaseAddress)) + if (apiFeatures == null || string.IsNullOrWhiteSpace(apiFeatures.BaseAddress)) { return base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); } - return RestApiExecuteAffrows(); + return RestApiExecuteAffrowsAsync().ConfigureAwait(false).GetAwaiter().GetResult(); } public override long ExecuteIdentity() => base.SplitExecuteIdentity( @@ -176,13 +177,13 @@ namespace FreeSql.QuestDb.Curd public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var apiFeatures = ServiceContainer.GetService(); - if (apiFeatures != null && string.IsNullOrWhiteSpace(apiFeatures.BaseAddress)) + if (apiFeatures == null || string.IsNullOrWhiteSpace(apiFeatures.BaseAddress)) { return base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); } - return Task.FromResult(RestApiExecuteAffrows()); + return RestApiExecuteAffrowsAsync(); } diff --git a/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbUpdate.cs b/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbUpdate.cs index eeff51ce5..5746e9777 100644 --- a/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbUpdate.cs +++ b/Providers/FreeSql.Provider.QuestDb/Curd/QuestDbUpdate.cs @@ -1,5 +1,7 @@ using FreeSql.Internal; using FreeSql.Internal.Model; +using FreeSql.Provider.QuestDb; +using FreeSql.Provider.QuestDb.Models; using Newtonsoft.Json; using System; using System.Collections; @@ -10,7 +12,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using FreeSql.Provider.QuestDb; namespace FreeSql.QuestDb.Curd { @@ -32,15 +33,16 @@ namespace FreeSql.QuestDb.Curd internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col); - private int RestApiExecuteAffrows() + private async Task RestApiExecuteAffrowsAsync() { var apiFeatures = ServiceContainer.GetService(); var sql = ToSql(); - var execAsync = apiFeatures.ExecAsync(sql).GetAwaiter().GetResult(); - var resultHash = new Hashtable(); + + var execAsync = await apiFeatures.ExecAsync(sql); + var result = new RestApiExecResponseJsonBody(); try { - resultHash = JsonConvert.DeserializeObject(execAsync); + result = JsonConvert.DeserializeObject(execAsync); } catch { @@ -50,22 +52,20 @@ namespace FreeSql.QuestDb.Curd } } - var ddl = resultHash["ddl"]?.ToString(); - var updated = Convert.ToInt32(resultHash["updated"]); - return ddl?.ToLower() == "ok" ? updated : 0; + return result.IsSuccessful ? result.Updated : 0; } public override int ExecuteAffrows() { //如果设置了RestApi 则走HTTP执行Sql var apiFeatures = ServiceContainer.GetService(); - if (apiFeatures != null && string.IsNullOrWhiteSpace(apiFeatures.BaseAddress)) + if (apiFeatures == null || string.IsNullOrWhiteSpace(apiFeatures.BaseAddress)) { return base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); } - return RestApiExecuteAffrows(); + return RestApiExecuteAffrowsAsync().ConfigureAwait(false).GetAwaiter().GetResult(); } protected override List ExecuteUpdated(IEnumerable columns) => @@ -187,13 +187,13 @@ namespace FreeSql.QuestDb.Curd public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var apiFeatures = ServiceContainer.GetService(); - if (apiFeatures != null && string.IsNullOrWhiteSpace(apiFeatures.BaseAddress)) + if (apiFeatures == null || string.IsNullOrWhiteSpace(apiFeatures.BaseAddress)) { return base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); } - return Task.FromResult(RestApiExecuteAffrows()); + return RestApiExecuteAffrowsAsync(); } diff --git a/Providers/FreeSql.Provider.QuestDb/Models/QuestResetApiFeatures.cs b/Providers/FreeSql.Provider.QuestDb/Models/QuestResetApiFeatures.cs new file mode 100644 index 000000000..e26f6bed6 --- /dev/null +++ b/Providers/FreeSql.Provider.QuestDb/Models/QuestResetApiFeatures.cs @@ -0,0 +1,26 @@ +using System.Net.Http; +using System.Threading.Tasks; +using System.Web; + +namespace FreeSql.Provider.QuestDb.Models +{ + internal class QuestResetApiFeatures + { + internal string BaseAddress { get; set; } + + internal string BasicToken { get; set; } + + internal HttpClient HttpClient => ServiceContainer.GetService().CreateClient("QuestDb"); + + internal async Task ExecAsync(string sql) + { + //HTTP GET 执行SQL + var url = $"exec?query={HttpUtility.UrlEncode(sql)}"; + if (!string.IsNullOrWhiteSpace(BasicToken)) + HttpClient.DefaultRequestHeaders.Add("Authorization", BasicToken); + var httpResponseMessage = await HttpClient.GetAsync(url); + var result = await httpResponseMessage.Content.ReadAsStringAsync(); + return result; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.QuestDb/Models/RestApiExecResponseJsonBody.cs b/Providers/FreeSql.Provider.QuestDb/Models/RestApiExecResponseJsonBody.cs new file mode 100644 index 000000000..f12e57f33 --- /dev/null +++ b/Providers/FreeSql.Provider.QuestDb/Models/RestApiExecResponseJsonBody.cs @@ -0,0 +1,21 @@ +using System; +using Newtonsoft.Json; + +namespace FreeSql.Provider.QuestDb.Models +{ + internal class RestApiExecResponseJsonBody + { + [JsonProperty("ddl")] + public string Ddl { get; set; } + + [JsonProperty("dml")] + public string Dml { get; set; } + + [JsonProperty("updated")] + public int Updated { get; set; } + + [JsonIgnore] + public bool IsSuccessful => string.Equals(Ddl, "ok", StringComparison.CurrentCultureIgnoreCase) || + string.Equals(Dml, "ok", StringComparison.CurrentCultureIgnoreCase); + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.QuestDb/QuestDbGlobalExtensions.cs b/Providers/FreeSql.Provider.QuestDb/QuestDbGlobalExtensions.cs index aff85f716..4475cc3c7 100644 --- a/Providers/FreeSql.Provider.QuestDb/QuestDbGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.QuestDb/QuestDbGlobalExtensions.cs @@ -1,15 +1,14 @@ using CsvHelper; using FreeSql; -using FreeSql.Internal.CommonProvider; -using FreeSql.Internal.Model; +using FreeSql.Provider.QuestDb; +using FreeSql.Provider.QuestDb.Models; using FreeSql.QuestDb; using FreeSql.QuestDb.Curd; +using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; -using Npgsql; using System; using System.Collections; using System.Collections.Generic; -using System.Data; using System.Globalization; using System.IO; using System.Linq; @@ -18,10 +17,6 @@ using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Web; -using FreeSql.Provider.QuestDb; -using System.Net; -using Microsoft.Extensions.DependencyInjection; public static partial class QuestDbGlobalExtensions { @@ -50,7 +45,12 @@ public static partial class QuestDbGlobalExtensions //初始化容器,添加HttpClient ServiceContainer.Initialize(service => { - service.AddHttpClient("QuestDb", client => client.BaseAddress = new Uri(host)) + var apiFeatures = new QuestResetApiFeatures + { + BaseAddress = host.StartsWith("http") ? host : $"http://{host}" + }; + + service.AddHttpClient("QuestDb", client => client.BaseAddress = new Uri(apiFeatures.BaseAddress)) .ConfigurePrimaryHttpMessageHandler(handlerBuilder => { //忽略SSL验证 @@ -62,18 +62,13 @@ public static partial class QuestDbGlobalExtensions }; }); - var description = new QuestResetApiFeatures() - { - BaseAddress = host - }; - if (!string.IsNullOrWhiteSpace(username) && !string.IsNullOrWhiteSpace(password)) { var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}")); - description.BasicToken = $"Basic {base64}"; + apiFeatures.BasicToken = $"Basic {base64}"; } - service.AddSingleton(description); + service.AddSingleton(apiFeatures); }); //RestApi需要无参数 @@ -349,24 +344,4 @@ static class LatestOnExtension var _partition = expressionVisitor.Fields(); LatestOnString.Value = string.Format(latestOnTemple, _timestamp, _partition); } -} - -internal class QuestResetApiFeatures -{ - internal string BaseAddress { get; set; } - - internal string BasicToken { get; set; } - - internal HttpClient HttpClient => ServiceContainer.GetService().CreateClient("QuestDb"); - - internal async Task ExecAsync(string sql) - { - //HTTP GET 执行SQL - var url = $"exec?query={HttpUtility.UrlEncode(sql)}"; - if (!string.IsNullOrWhiteSpace(BasicToken)) - HttpClient.DefaultRequestHeaders.Add("Authorization", BasicToken); - var httpResponseMessage = await HttpClient.GetAsync(url); - var result = await httpResponseMessage.Content.ReadAsStringAsync(); - return result; - } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.QuestDb/ServiceContainer.cs b/Providers/FreeSql.Provider.QuestDb/ServiceContainer.cs index 628dd7faf..90b1b0255 100644 --- a/Providers/FreeSql.Provider.QuestDb/ServiceContainer.cs +++ b/Providers/FreeSql.Provider.QuestDb/ServiceContainer.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Net.Http; using System.Text; @@ -23,4 +24,5 @@ namespace FreeSql.Provider.QuestDb return _serviceProvider == null ? default : _serviceProvider.GetService(); } } + } \ No newline at end of file