This commit is contained in:
hyzx86 2023-06-07 19:24:30 +08:00
commit 092bd4f3f6
118 changed files with 2702 additions and 536 deletions

View File

@ -11,7 +11,7 @@
<!-- <!--
经常出于版本交叉问题,暂时关闭,在每个项目上设置版本号 经常出于版本交叉问题,暂时关闭,在每个项目上设置版本号
<PropertyGroup> <PropertyGroup>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
--> -->

View File

@ -34,12 +34,12 @@ namespace aspnetcore_transaction.Controllers
} }
[HttpGet("2")] [HttpGet("2")]
//[Transactional] [Transactional]
public async Task<object> GetAsync([FromServices] BaseRepository<Song> repoSong, [FromServices] BaseRepository<Detail> repoDetail, [FromServices] SongRepository repoSong2, public async Task<object> GetAsync([FromServices] BaseRepository<Song> repoSong, [FromServices] BaseRepository<Detail> repoDetail, [FromServices] SongRepository repoSong2,
[FromServices] SongService serviceSong) [FromServices] SongService serviceSong)
{ {
await serviceSong.Test2(); await repoSong.InsertAsync(new Song());
await serviceSong.Test3(); await repoDetail.InsertAsync(new Detail());
return "111"; return "111";
} }
} }

View File

@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace aspnetcore_transaction namespace aspnetcore_transaction
{ {
@ -12,6 +13,11 @@ namespace aspnetcore_transaction
public static IHostBuilder CreateHostBuilder(string[] args) => public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args) Host.CreateDefaultBuilder(args)
.ConfigureLogging(loggerBuilder =>
{
loggerBuilder.SetMinimumLevel(LogLevel.Critical);
//loggerBuilder.ClearProviders();
})
.ConfigureWebHostDefaults(webBuilder => .ConfigureWebHostDefaults(webBuilder =>
{ {
webBuilder.UseStartup<Startup>(); webBuilder.UseStartup<Startup>();

View File

@ -2,6 +2,7 @@
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading;
using aspnetcore_transaction.Controllers; using aspnetcore_transaction.Controllers;
using FreeSql; using FreeSql;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
@ -17,14 +18,18 @@ namespace aspnetcore_transaction
{ {
Configuration = configuration; Configuration = configuration;
Fsql = new FreeSqlBuilder() Fsql = new FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\test_trans.db") .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=50;TrustServerCertificate=true")
.UseAutoSyncStructure(true) .UseAutoSyncStructure(true)
.UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText)) //.UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText))
.UseNoneCommandParameter(true) .UseNoneCommandParameter(true)
.Build(); .Build();
Fsql.Aop.TraceBefore += (_, e) => Trace.WriteLine($"----TraceBefore---{e.Identifier} {e.Operation}"); //Fsql.Aop.TraceBefore += (_, e) => Trace.WriteLine($"----TraceBefore---{e.Identifier} {e.Operation}");
Fsql.Aop.TraceAfter += (_, e) => Trace.WriteLine($"----TraceAfter---{e.Identifier} {e.Operation} {e.Remark} {e.Exception?.Message} {e.ElapsedMilliseconds}ms\r\n"); Fsql.Aop.TraceAfter += (_, e) =>
{
//Trace.WriteLine($"----TraceAfter---{e.Identifier} {e.Operation} {e.Remark} {e.Exception?.Message} {e.ElapsedMilliseconds}ms\r\n");
if (e.Exception != null && e.Exception.Message.StartsWith("【主库】状态不可用,等待后台检查程序恢复方可使用。") == false) Console.WriteLine(e.Exception.Message + " === " + Fsql.Ado.MasterPool.Statistics);
};
} }
public IConfiguration Configuration { get; } public IConfiguration Configuration { get; }
@ -32,6 +37,8 @@ namespace aspnetcore_transaction
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
ThreadPool.SetMinThreads(1000, 1000);
services.AddControllersWithViews(); services.AddControllersWithViews();
services.AddSingleton<IFreeSql>(Fsql); services.AddSingleton<IFreeSql>(Fsql);

View File

@ -38,6 +38,7 @@ namespace FreeSql
if (context.Exception == null) _uow.Commit(); if (context.Exception == null) _uow.Commit();
else _uow.Rollback(); else _uow.Rollback();
} }
catch { }
finally finally
{ {
_uow.Dispose(); _uow.Dispose();

View File

@ -14,6 +14,7 @@ using Npgsql;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Data.Common; using System.Data.Common;
using System.Data.Odbc; using System.Data.Odbc;
using System.Data.SqlClient; using System.Data.SqlClient;
@ -483,6 +484,29 @@ namespace base_entity
public string Name { get; set; } public string Name { get; set; }
} }
[Table(Name = "class_{0}")]
public class Class1111
{
[Column(IsPrimary = true, IsIdentity = true, IsNullable = false)]
public int Id { get; set; }
[Column(StringLength = 20, IsNullable = false)]
public string Name { get; set; }
}
[Table(Name = "student_{0}")]
public class Student2222
{
[Column(IsPrimary = true, IsIdentity = true, IsNullable = false)]
public int Id { get; set; }
[Column(IsPrimary = false, IsNullable = false)]
public int ClassId { get; set; }
[Column(StringLength = 20, IsNullable = false)]
public string Name { get; set; }
}
static void Main(string[] args) static void Main(string[] args)
{ {
var pams = new Dictionary<string, string>(); var pams = new Dictionary<string, string>();
@ -542,11 +566,11 @@ namespace base_entity
.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;min pool size=1;Max pool size=2;AllowLoadLocalInfile=true") .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;min pool size=1;Max pool size=2;AllowLoadLocalInfile=true")
.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3;TrustServerCertificate=true") //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3;TrustServerCertificate=true")
//.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2")
//.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=toc;Pooling=true;Maximum Pool Size=2") //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=toc;Pooling=true;Maximum Pool Size=2")
//.UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) .UseNameConvert(FreeSql.Internal.NameConvertType.ToLower)
//.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2")
//.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) //.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper)
@ -577,37 +601,21 @@ namespace base_entity
BaseEntity.Initialization(fsql, () => _asyncUow.Value); BaseEntity.Initialization(fsql, () => _asyncUow.Value);
#endregion #endregion
var bulkUsers = new[] {
new IdentityUser1 { Nickname = "nickname11", Username = "username11" },
new IdentityUser1 { Nickname = "nickname12", Username = "username12" },
new IdentityUser1 { Nickname = "nickname13", Username = "username13" },
new IdentityUser1 { Nickname = "nickname21", Username = "username21" },
new IdentityUser1 { Nickname = "nickname22", Username = "username22" },
new IdentityUser1 { Nickname = "nickname23", Username = "username23" }
};
fsql.Insert(bulkUsers).NoneParameter().ExecuteAffrows();
fsql.Insert(bulkUsers).IgnoreInsertValueSql(a => a.Nickname).NoneParameter().ExecuteAffrows();
bulkUsers = fsql.Select<IdentityUser1>().OrderByDescending(a => a.Id).Limit(3).ToList().ToArray();
bulkUsers[0].Nickname += "_bulkupdate";
bulkUsers[1].Nickname += "_bulkupdate";
bulkUsers[2].Nickname += "_bulkupdate";
fsql.Update<IdentityUser1>().SetSource(bulkUsers).ExecuteSqlBulkCopy();
var objtsql1 = fsql.Select<object>().WithSql("select * from user1").ToList(); var sqlastable1 = fsql.Select<CurrentDetail>(101).AsTable((t, o) => "current_detail_230501").ToSql();
var objtsql2 = fsql.Select<object>().WithSql("select * from user1").ToList<User1>(); var sqlastable2 = fsql.Update<CurrentDetail>(101).AsTable("current_detail_230501").Set(t => t.StatuId, 1).ToSql();
var sqlastable3 = fsql.Delete<CurrentDetail>(101).AsTable("current_detail_230501").ToSql();
var astsql = fsql.Select<AsTableLog, Sys_owner>() var astsql = fsql.Select<AsTableLog, Sys_owner>()
.InnerJoin((a, b) => a.id == b.Id) .InnerJoin((a, b) => a.id == b.Id)
.OrderBy((a,b) => a.createtime) .OrderBy((a, b) => a.createtime)
.ToSql(); .ToSql();
//var table = fsql.CodeFirst.GetTableByEntity(typeof(AsTableLog)); //var table = fsql.CodeFirst.GetTableByEntity(typeof(AsTableLog));
//table.SetAsTable(new ModAsTableImpl(fsql), table.ColumnsByCs[nameof(AsTableLog.click)]); //table.SetAsTable(new ModAsTableImpl(fsql), table.ColumnsByCs[nameof(AsTableLog.click)]);
var testitems = new[] var testitems = new[]
{ {
new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11"), click = 1 }, new AsTableLog{ msg = "msg01", createtime = DateTime.Parse("2022-1-1 13:00:11"), click = 1 },
@ -625,6 +633,10 @@ namespace base_entity
var sqlat = sqlatb.ToSql(); var sqlat = sqlatb.ToSql();
var sqlatr = sqlatb.ExecuteAffrows(); var sqlatr = sqlatb.ExecuteAffrows();
//var sqlatc1 = fsql.Delete<AsTableLog>().Where(a => a.click < 0);
//var sqlatca1 = sqlatc1.ToSql();
//var sqlatcr1 = sqlatc1.ExecuteAffrows();
var sqlatc1 = fsql.Delete<AsTableLog>().Where(a => a.id == Guid.NewGuid() && a.createtime == DateTime.Parse("2022-3-8 15:00:13")); var sqlatc1 = fsql.Delete<AsTableLog>().Where(a => a.id == Guid.NewGuid() && a.createtime == DateTime.Parse("2022-3-8 15:00:13"));
var sqlatca1 = sqlatc1.ToSql(); var sqlatca1 = sqlatc1.ToSql();
var sqlatcr1 = sqlatc1.ExecuteAffrows(); var sqlatcr1 = sqlatc1.ExecuteAffrows();
@ -715,6 +727,101 @@ namespace base_entity
}); });
var iouSetSql01 = fsql.InsertOrUpdate<User1>()
.SetSource(Enumerable.Range(0, 5).Select(a => new User1 { Id = Guid.NewGuid(), Nickname = $"nickname{a}", Username = $"username{a}", Description = $"desc{a}" }).ToArray())
.UpdateSet((a, b) => a.Sort == b.Sort + 10)
.UpdateSet((a, b) => a.Nickname == "xxx")
.ToSql();
fsql.Delete<OracleLongRaw1>().Where("1=1").ExecuteAffrows();
var longRawData = Encoding.UTF8.GetBytes(string.Join(",", Enumerable.Range(1, 2000).Select(a => "中国人")));
fsql.Insert(new OracleLongRaw1 { data = longRawData }).NoneParameter(false).ExecuteAffrows();
fsql.Insert(new OracleLongRaw1 { data = longRawData }).NoneParameter(true).ExecuteAffrows();
var longRaw1 = fsql.Select<OracleLongRaw1>().ToList();
MarketingRestrictions restrictions = new MarketingRestrictions();
if (restrictions.Id == Guid.Empty)
{
restrictions.CreatedBy = 100;
}
else
{
restrictions.UpdatedBy = 100;
restrictions.UpdatedTime = DateTime.Now;
}
int ret = fsql.InsertOrUpdate<MarketingRestrictions>()
.SetSource(restrictions)
.UpdateColumns(r => new {
r.Describe,
r.IsLimitUsePoints,
r.Status,
r.StartTime,
r.EndTime,
r.UpdatedBy,
r.UpdatedTime
})
.ExecuteAffrows();
var query2222 = fsql.Select<Student2222>()
.AsTable((t, o) => string.Format(o, "hash2"))
.Where(p => p.Name.Contains("search"))
.GroupBy(a => new { a.ClassId })
.WithTempQuery(a => a.Key);
var sql11111 = fsql.Select<Class1111>()
.AsTable((t, o) => string.Format(o, "hash1"))
.Where(s => query2222
.ToList(p => p.ClassId)
.Contains(s.Id))
.ToSql(s => new
{
s.Id,
s.Name,
});
var isusers01 = fsql.Select<Achievement>()
.Where(e => e.Property("项目执行情况") == "结题")
.GroupBy(e => new { ProjectLevel = e.Property("项目级别") })
.ToSql(e => new
{
e.Key.ProjectLevel,
Test = e.Value.Group.Property("批准经费总额(万元)"),
});
isusers01 = fsql.Select<Achievement>()
.Where(e => e.Property("项目执行情况") == "结题")
.GroupBy(e => new { ProjectLevel = e.Property("项目级别") })
.WithTempQuery(e => new
{
e.Key.ProjectLevel,
Test = e.Value.Group.Property("批准经费总额(万元)"),
})
.ToSql();
var bulkUsers = new[] {
new IdentityUser1 { Nickname = "nickname11", Username = "username11" },
new IdentityUser1 { Nickname = "nickname12", Username = "username12" },
new IdentityUser1 { Nickname = "nickname13", Username = "username13" },
new IdentityUser1 { Nickname = "nickname21", Username = "username21" },
new IdentityUser1 { Nickname = "nickname22", Username = "username22" },
new IdentityUser1 { Nickname = "nickname23", Username = "username23" }
};
fsql.Insert(bulkUsers).NoneParameter().ExecuteAffrows();
fsql.Insert(bulkUsers).IgnoreInsertValueSql(a => a.Nickname).NoneParameter().ExecuteAffrows();
bulkUsers = fsql.Select<IdentityUser1>().OrderByDescending(a => a.Id).Limit(3).ToList().ToArray();
bulkUsers[0].Nickname += "_bulkupdate";
bulkUsers[1].Nickname += "_bulkupdate";
bulkUsers[2].Nickname += "_bulkupdate";
fsql.Update<IdentityUser1>().SetSource(bulkUsers).ExecuteSqlBulkCopy();
var objtsql1 = fsql.Select<object>().WithSql("select * from user1").ToList();
var objtsql2 = fsql.Select<object>().WithSql("select * from user1").ToList<User1>();
var usergroupRepository = fsql.GetAggregateRootRepository<UserGroup>(); var usergroupRepository = fsql.GetAggregateRootRepository<UserGroup>();
usergroupRepository.Delete(a => true); usergroupRepository.Delete(a => true);
usergroupRepository.Insert(new[]{ usergroupRepository.Insert(new[]{
@ -2116,4 +2223,178 @@ namespace base_entity
public string GoodsNo { get; set; } public string GoodsNo { get; set; }
public string GoodsName { get; set; } public string GoodsName { get; set; }
} }
[ExpressionCall]
public static class AchievementExpressionExtension
{
static ThreadLocal<ExpressionCallContext> context = new ThreadLocal<ExpressionCallContext>();
public static string Property(this Achievement achievement, string fieldName)
{
var ctx = context.Value;
var prefix = ctx.ParsedContent["achievement"];
prefix = prefix.Substring(0, prefix.IndexOf('.') + 1);
ctx.Result = prefix + $"`{fieldName}`";
return default;
}
}
[Table(DisableSyncStructure = true)]
public class Achievement
{
[Column(MapType = typeof(string))]
public Achievement Group { get; set; }
}
[Description("营销限制表")]
[Table(Name = "MarketingRestrictions")]
public class MarketingRestrictions
{
/// <summary>
/// 主键标识
/// </summary>
[Description("主键标识")]
[Column(DbType = "uniqueidentifier", IsPrimary = true)]
public Guid Id { get; set; }
/// <summary>
/// 商户应用Id
/// </summary>
[Description("商户应用Id")]
[Column(DbType = "varchar(32) not null")]
public string MchtAppId { get; set; }
/// <summary>
/// 描述
/// </summary>
[Description("描述")]
[Column(DbType = "nvarchar(500) not null")]
public string Describe { get; set; }
/// <summary>
/// 状态0、关闭 1、启用
/// </summary>
[Description("状态0、关闭 1、启用")]
[Column(DbType = "smallint")]
public sbyte Status { get; set; }
/// <summary>
/// 是否限制使用积分0、否 1、是
/// </summary>
[Description("是否限制使用积分0、否 1、是")]
[Column(DbType = "smallint")]
public sbyte IsLimitUsePoints { get; set; }
/// <summary>
/// 开始时间
/// </summary>
[Description("开始时间")]
[Column(DbType = "datetime")]
public DateTime StartTime { get; set; }
/// <summary>
/// 结束时间
/// </summary>
[Description("结束时间")]
[Column(DbType = "datetime")]
public DateTime EndTime { get; set; }
/// <summary>
/// 创建人Id
/// </summary>
[Description("创建人Id")]
[Column(DbType = "bigint")]
public long CreatedBy { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[Description("创建时间")]
[Column(DbType = "datetime", ServerTime = DateTimeKind.Local, CanUpdate = false)]
public DateTime CreatedTime { get; set; }
/// <summary>
/// 最后编辑人Id
/// </summary>
[Description("最后编辑人Id")]
[Column(DbType = "bigint")]
public long? UpdatedBy { get; set; }
/// <summary>
/// 最后编辑时间
/// </summary>
[Description("最后编辑时间")]
[Column(DbType = "datetime")]
public DateTime? UpdatedTime { get; set; }
/// <summary>
/// 是否删除0、否 1、是
/// </summary>
[Description("是否删除0、否 1、是")]
[Column(DbType = "smallint")]
public sbyte Deleted { get; set; }
/// <summary>
/// 删除人Id
/// </summary>
[Description("删除人Id")]
[Column(DbType = "bigint")]
public long? DeletedBy { get; set; }
/// <summary>
/// 删除时间
/// </summary>
[Description("删除时间")]
[Column(DbType = "datetime")]
public DateTime? DeletedTime { get; set; }
}
class OracleLongRaw1
{
public Guid id { get; set; }
[Column(DbType = "long raw")]
public byte[] data { get; set; }
}
[Table(Name = "current_detail_{yyMM01}", AsTable = "recordDate=2022-12-01(1 month)", DisableSyncStructure = true)]
public class CurrentDetail
{
[Column(IsPrimary = true)]
public long Id { get; set; }
public DateTime CreateTime { get; set; } = DateTime.Now;
/// <summary>
/// 创建日期
/// </summary>
public DateTime RecordDate { get; set; }
/// <summary>
/// 创建小时
/// </summary>
public int RecordHour { get; set; }
/// <summary>
/// 根据当前分钟数规整到10分钟的倍数
/// 例如 21分=>20分
/// </summary>
public int RecordMinute { get; set; }
/// <summary>
/// 记录时间
/// </summary>
public DateTime RecordTime { get; set; }
/// <summary>
/// 设备Code
/// </summary>
public int DeviceCode { get; set; }
/// <summary>
/// 控制器序列号
/// </summary>
public string TerminalSequence { get; set; }
/// <summary>
/// 平均值
/// </summary>
public float AvgValue { get; set; }
/// <summary>
/// 路数
/// </summary>
public int RouteNum { get; set; }
/// <summary>
/// 相类型
/// </summary>
public int PhaseTypeId { get; set; }
public int StatuId { get; set; }
}
} }

View File

@ -180,6 +180,122 @@
更新时间 更新时间
</summary> </summary>
</member> </member>
<member name="P:base_entity.MarketingRestrictions.Id">
<summary>
主键标识
</summary>
</member>
<member name="P:base_entity.MarketingRestrictions.MchtAppId">
<summary>
商户应用Id
</summary>
</member>
<member name="P:base_entity.MarketingRestrictions.Describe">
<summary>
描述
</summary>
</member>
<member name="P:base_entity.MarketingRestrictions.Status">
<summary>
状态0、关闭 1、启用
</summary>
</member>
<member name="P:base_entity.MarketingRestrictions.IsLimitUsePoints">
<summary>
是否限制使用积分0、否 1、是
</summary>
</member>
<member name="P:base_entity.MarketingRestrictions.StartTime">
<summary>
开始时间
</summary>
</member>
<member name="P:base_entity.MarketingRestrictions.EndTime">
<summary>
结束时间
</summary>
</member>
<member name="P:base_entity.MarketingRestrictions.CreatedBy">
<summary>
创建人Id
</summary>
</member>
<member name="P:base_entity.MarketingRestrictions.CreatedTime">
<summary>
创建时间
</summary>
</member>
<member name="P:base_entity.MarketingRestrictions.UpdatedBy">
<summary>
最后编辑人Id
</summary>
</member>
<member name="P:base_entity.MarketingRestrictions.UpdatedTime">
<summary>
最后编辑时间
</summary>
</member>
<member name="P:base_entity.MarketingRestrictions.Deleted">
<summary>
是否删除0、否 1、是
</summary>
</member>
<member name="P:base_entity.MarketingRestrictions.DeletedBy">
<summary>
删除人Id
</summary>
</member>
<member name="P:base_entity.MarketingRestrictions.DeletedTime">
<summary>
删除时间
</summary>
</member>
<member name="P:base_entity.CurrentDetail.RecordDate">
<summary>
创建日期
</summary>
</member>
<member name="P:base_entity.CurrentDetail.RecordHour">
<summary>
创建小时
</summary>
</member>
<member name="P:base_entity.CurrentDetail.RecordMinute">
<summary>
根据当前分钟数规整到10分钟的倍数
例如 21分=>20分
</summary>
</member>
<member name="P:base_entity.CurrentDetail.RecordTime">
<summary>
记录时间
</summary>
</member>
<member name="P:base_entity.CurrentDetail.DeviceCode">
<summary>
设备Code
</summary>
</member>
<member name="P:base_entity.CurrentDetail.TerminalSequence">
<summary>
控制器序列号
</summary>
</member>
<member name="P:base_entity.CurrentDetail.AvgValue">
<summary>
平均值
</summary>
</member>
<member name="P:base_entity.CurrentDetail.RouteNum">
<summary>
路数
</summary>
</member>
<member name="P:base_entity.CurrentDetail.PhaseTypeId">
<summary>
相类型
</summary>
</member>
<member name="T:EMSServerModel.Model.Role"> <member name="T:EMSServerModel.Model.Role">
<summary> <summary>
角色表 角色表

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -19,7 +19,7 @@
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -15,7 +15,7 @@
<Title>$(AssemblyName)</Title> <Title>$(AssemblyName)</Title>
<IsPackable>true</IsPackable> <IsPackable>true</IsPackable>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo> <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -13,7 +13,7 @@
<PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl> <PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl>
<RepositoryUrl>https://github.com/2881099/FreeSql</RepositoryUrl> <RepositoryUrl>https://github.com/2881099/FreeSql</RepositoryUrl>
<PackageTags>FreeSql DbFirst 实体生成器</PackageTags> <PackageTags>FreeSql DbFirst 实体生成器</PackageTags>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -17,7 +17,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -17,7 +17,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -17,7 +17,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -22,16 +22,20 @@ namespace FreeSql.Tests.Provider.Xugu
public void GetTableByName() public void GetTableByName()
{ {
var fsql = g.xugu; var fsql = g.xugu;
var t1 = fsql.DbFirst.GetTableByName("GENERAL.system_log"); fsql.CodeFirst.SyncStructure(typeof(test_existstb01));
Assert.NotNull(t1); var t1 = fsql.DbFirst.GetTableByName("test_existstb01");
Assert.True(t1.Columns.Count > 0); Assert.NotNull(t1);
Assert.True(t1.Columns.Count > 0);
var t3 = fsql.DbFirst.GetTableByName("notexists_tb");
Assert.Null(t3);
fsql.Ado.ExecuteNonQuery("drop table test_existstb01");
} }
[Fact] [Fact]
public void ExistsTable() public void ExistsTable()
{ {
var fsql = g.xugu; var fsql = g.xugu;
Assert.False(fsql.DbFirst.ExistsTable("GENERAL.system_log")); Assert.False(fsql.DbFirst.ExistsTable("test_existstb01"));
fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); fsql.CodeFirst.SyncStructure(typeof(test_existstb01));
Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); Assert.True(fsql.DbFirst.ExistsTable("test_existstb01"));
fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); fsql.Ado.ExecuteNonQuery("drop table test_existstb01");

View File

@ -0,0 +1,239 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FreeSql.DataAnnotations;
using FreeSql.Extensions.DynamicEntity;
using Newtonsoft.Json;
using Xunit;
namespace FreeSql.Tests.DynamicEntity
{
public class DynamicEntityTest
{
private static IFreeSql fsql = new FreeSqlBuilder().UseConnectionString(DataType.Sqlite,
"data source=:memory:")
.UseMonitorCommand(d => Console.WriteLine(d.CommandText)).Build();
[Fact]
public void NormalTest()
{
var table = fsql.CodeFirst.DynamicEntity("NormalUsers")
.Property("Id", typeof(string))
.Property("Name", typeof(string))
.Property("Address", typeof(string))
.Build();
var dict = new Dictionary<string, object>
{
["Name"] = "张三",
["Id"] = Guid.NewGuid().ToString(),
["Address"] = "北京市"
};
var instance = table.CreateInstance(dict);
//根据Type生成表
fsql.CodeFirst.SyncStructure(table.Type);
fsql.Insert<object>().AsType(table.Type).AppendData(instance).ExecuteAffrows();
var objects = fsql.Select<object>().AsType(table.Type).ToList();
}
[Fact]
public void AttributeTest()
{
var table = fsql.CodeFirst.DynamicEntity("AttributeUsers",
new TableAttribute() { Name = "T_Attribute_User" },
new IndexAttribute("Name_Index1", "Name", false))
.Property("Id", typeof(int),
new ColumnAttribute() { IsPrimary = true, IsIdentity = true, Position = 1 })
.Property("Name", typeof(string),
new ColumnAttribute() { StringLength = 20, Position = 2 })
.Property("Address", typeof(string),
new ColumnAttribute() { StringLength = 150, Position = 3 })
.Build();
var dict = new Dictionary<string, object>
{
["Name"] = "张三",
["Address"] = "北京市"
};
var instance = table.CreateInstance(dict);
//根据Type生成表
fsql.CodeFirst.SyncStructure(table.Type);
var insertId = fsql.Insert<object>().AsType(table.Type).AppendData(instance).ExecuteIdentity();
var select = fsql.Select<object>().AsType(table.Type).ToList();
}
[Fact]
public void SuperClassTest()
{
var table = fsql.CodeFirst.DynamicEntity("Roles", new TableAttribute() { Name = "T_Role" },
new IndexAttribute("Name_Index2", "Name", false))
.Extend(typeof(BaseModel))
.Property("Id", typeof(int),
new ColumnAttribute() { IsPrimary = true, IsIdentity = true, Position = 1 })
.Property("Name", typeof(string),
new ColumnAttribute() { StringLength = 20, Position = 2 })
.Build();
var dict = new Dictionary<string, object>
{
["Name"] = "系统管理员",
["UpdateTime"] = DateTime.Now,
["UpdatePerson"] = "admin"
};
var instance = table.CreateInstance(dict);
//根据Type生成表
fsql.CodeFirst.SyncStructure(table.Type);
fsql.Insert<object>().AsType(table.Type).AppendData(instance).ExecuteAffrows();
var objects = fsql.Select<object>().AsType(table.Type).ToList();
}
[Fact]
public void SuperClassVirtualOverrideTest()
{
var table = fsql.CodeFirst.DynamicEntity("Role_VirtualOverride",
new TableAttribute() { Name = "T_Role_VirtualOverride" },
new IndexAttribute("Name_Index2", "Name", false))
.Extend(typeof(BaseModelOverride))
.Property("Id", typeof(int),
new ColumnAttribute() { IsPrimary = true, IsIdentity = true, Position = 1 })
.Property("Name", typeof(string),
new ColumnAttribute() { StringLength = 20, Position = 2 })
.Property("Operators", typeof(string), true) //重写 virtual 属性
.Build();
var dict = new Dictionary<string, object>
{
["Name"] = "系统管理员",
["UpdateTime"] = DateTime.Now,
["UpdatePerson"] = "admin",
["Operators"] = "manager"
};
var instance = table.CreateInstance(dict);
//根据Type生成表
fsql.CodeFirst.SyncStructure(table.Type);
fsql.Insert<object>().AsType(table.Type).AppendData(instance).ExecuteAffrows();
var objects = fsql.Select<object>().AsType(table.Type).ToList();
}
[Fact]
public void SuperClassBaseModelAbstractTest()
{
var table = fsql.CodeFirst.DynamicEntity("Role_AbstractOverride",
new TableAttribute() { Name = "T_Role_AbstractOverride" },
new IndexAttribute("Name_Index2", "Name", false))
.Extend(typeof(BaseModelAbstract))
.Property("Id", typeof(int),
new ColumnAttribute() { IsPrimary = true, IsIdentity = true, Position = 1 })
.Property("Name", typeof(string),
new ColumnAttribute() { StringLength = 20, Position = 2 })
.Property("Operators", typeof(string), true) //重写 abstract 属性
.Build();
var dict = new Dictionary<string, object>
{
["Name"] = "系统管理员",
["UpdateTime"] = DateTime.Now,
["UpdatePerson"] = "admin",
["Operators"] = "manager"
};
var instance = table.CreateInstance(dict);
//根据Type生成表
fsql.CodeFirst.SyncStructure(table.Type);
fsql.Insert<object>().AsType(table.Type).AppendData(instance).ExecuteAffrows();
var objects = fsql.Select<object>().AsType(table.Type).ToList();
}
[Fact]
public void SuperClassBaseModelAbstractAndVirtualTest()
{
var table = fsql.CodeFirst.DynamicEntity("Role_AbstractAndVirtualOverride",
new TableAttribute() { Name = "Role_AbstractAndVirtualOverride" },
new IndexAttribute("Name_Index2", "Name", false))
.Extend(typeof(BaseModelAbstractAndVirtual))
.Property("Id", typeof(int),
new ColumnAttribute() { IsPrimary = true, IsIdentity = true, Position = 1 })
.Property("Name", typeof(string),
new ColumnAttribute() { StringLength = 20, Position = 2 })
.Property("Operators", typeof(string), true) //重写 abstract 属性
.Property("Operators2", typeof(string), true) //重写 virtual 属性
.Build();
var dict = new Dictionary<string, object>
{
["Name"] = "系统管理员",
["UpdateTime"] = DateTime.Now,
["UpdatePerson"] = "admin",
["Operators"] = "manager",
["Operators2"] = "manager2"
};
var instance = table.CreateInstance(dict);
//根据Type生成表
fsql.CodeFirst.SyncStructure(table.Type);
fsql.Insert<object>().AsType(table.Type).AppendData(instance).ExecuteAffrows();
var objects = fsql.Select<object>().AsType(table.Type).ToList();
}
[Fact]
public void DefaultValueTest()
{
var table = fsql.CodeFirst.DynamicEntity("NormalUsers")
.Property("Id", typeof(string))
.Property("Age", typeof(int), false, 12)
.Property("Longs", typeof(long), false, 16666)
.Property("Dates", typeof(DateTime), false, "2023-05-15")
.Property("Name", typeof(char), false, '我')
.Property("Address", typeof(bool), false, false) //设置默认值
.Property("Money", typeof(double), false, 265421.02) //设置默认值
.Property("MoneyFloat", typeof(float), false, 26543.02) //设置默认值
.Property("MoneyDecimal", typeof(decimal), true, 2663.12560) //设置默认值
.Build();
var dict = new Dictionary<string, object>
{
["Id"] = Guid.NewGuid().ToString()
};
var instance = table.CreateInstance(dict);
//根据Type生成表
fsql.CodeFirst.SyncStructure(table.Type);
fsql.Insert<object>().AsType(table.Type).AppendData(instance).ExecuteAffrows();
var objects = fsql.Select<object>().AsType(table.Type).ToList();
}
}
public class BaseModel
{
[Column(Position = 99)] public DateTime UpdateTime { get; set; }
[Column(Position = 100, StringLength = 20)]
public string UpdatePerson { get; set; }
}
public class BaseModelOverride
{
[Column(Position = 99)] public DateTime UpdateTime { get; set; }
[Column(Position = 100, StringLength = 20)]
public string UpdatePerson { get; set; }
public virtual string Operators { get; set; }
}
public abstract class BaseModelAbstract
{
[Column(Position = 99)] public DateTime UpdateTime { get; set; }
[Column(Position = 100, StringLength = 20)]
public string UpdatePerson { get; set; }
public abstract string Operators { get; set; }
}
public abstract class BaseModelAbstractAndVirtual
{
[Column(Position = 99)] public DateTime UpdateTime { get; set; }
[Column(Position = 100, StringLength = 20)]
public string UpdatePerson { get; set; }
public abstract string Operators { get; set; }
public virtual string Operators2 { get; set; }
}
}

View File

@ -1,4 +1,4 @@
using FreeSql.DataAnnotations; using FreeSql.DataAnnotations;
using FreeSql.Tests.DataContext.SqlServer; using FreeSql.Tests.DataContext.SqlServer;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -30,6 +30,25 @@ namespace FreeSql.Tests.SqlServer
public DateTime CreateTime { get; set; } public DateTime CreateTime { get; set; }
} }
abstract class EntityBase
{
public int Id { get; set; }
}
class SysDictionnary : EntityBase
{
public string Name { get; set; }
}
[Fact]
public void AsType()
{
var fsql = g.sqlserver;
var delsid = new[] { 1, 2, 3, 4 };
var sqlsss22222 = fsql.Delete<object>().AsType(typeof(SysDictionnary))
.Where(o => delsid.Contains((o as EntityBase).Id))
.ToSql();
}
[Fact] [Fact]
public void Dywhere() public void Dywhere()
{ {

View File

@ -9,6 +9,213 @@ namespace FreeSql.Tests.SqlServer
{ {
public class SqlServerSelectWithTempQueryTest public class SqlServerSelectWithTempQueryTest
{ {
[Fact]
public void Issues1519()
{
var fsql = g.oracle;
var query = fsql.Select<Issues1510T1>()
.FromQuery(fsql.Select<Issues1510T2>().WithTempQuery(e => e))
.InnerJoin(t => t.t1.Id == t.t2.T1JoinId)
.WithTempQuery(t => new
{
t.t1.Id,
t.t1.Name,
T2Id = t.t2.Id,
T2Name = t.t1.Name,
});
var sql = query.ToSql();
Assert.Equal(sql, @"SELECT *
FROM (
SELECT a.""ID"", a.""NAME"", htb.""ID"" ""T2ID"", a.""NAME"" ""T2NAME""
FROM ""ISSUES1510T1"" a
INNER JOIN (
SELECT a.""ID"", a.""NAME"", a.""T1JOINID""
FROM ""ISSUES1510T2"" a ) htb ON a.""ID"" = htb.""T1JOINID"" ) a");
query.ToList();
query.Page(2, 5);
sql = query.ToSql();
Assert.Equal(sql, @"SELECT t.* FROM (SELECT a.*, ROWNUM AS ""__rownum__""
FROM (
SELECT a.""ID"", a.""NAME"", htb.""ID"" ""T2ID"", a.""NAME"" ""T2NAME""
FROM ""ISSUES1510T1"" a
INNER JOIN (
SELECT a.""ID"", a.""NAME"", a.""T1JOINID""
FROM ""ISSUES1510T2"" a ) htb ON a.""ID"" = htb.""T1JOINID"" ) a
WHERE ROWNUM < 11) t WHERE t.""__rownum__"" > 5");
query.ToList();
}
[Fact]
public void Issues1510()
{
var fsql = g.mysql;
var query = fsql.Select<Issues1510T1>()
.FromQuery(fsql.Select<Issues1510T2>().WithTempQuery(e => e))
.InnerJoin(t => t.t1.Id == t.t2.T1JoinId)
.WithTempQuery(t => new
{
t.t1.Id,
t.t1.Name,
T2Id = t.t2.Id,
T2Name = t.t1.Name,
});
var sql = query.ToSql();
Assert.Equal(sql, @"SELECT *
FROM (
SELECT a.`Id`, a.`Name`, htb.`Id` `T2Id`, a.`Name` `T2Name`
FROM `Issues1510T1` a
INNER JOIN (
SELECT a.`Id`, a.`Name`, a.`T1JoinId`
FROM `Issues1510T2` a ) htb ON a.`Id` = htb.`T1JoinId` ) a");
query.ToList();
query = fsql.Select<Issues1510T1>()
.FromQuery(fsql.Select<Issues1510T2>().WithTempQuery(e => e).WithTempQuery(e => e))
.InnerJoin(t => t.t1.Id == t.t2.T1JoinId)
.WithTempQuery(t => new
{
t.t1.Id,
t.t1.Name,
T2Id = t.t2.Id,
T2Name = t.t1.Name,
});
sql = query.ToSql();
Assert.Equal(sql, @"SELECT *
FROM (
SELECT a.`Id`, a.`Name`, htb.`Id` `T2Id`, a.`Name` `T2Name`
FROM `Issues1510T1` a
INNER JOIN (
SELECT a.`Id`, a.`Name`, a.`T1JoinId`
FROM (
SELECT a.`Id`, a.`Name`, a.`T1JoinId`
FROM `Issues1510T2` a ) a ) htb ON a.`Id` = htb.`T1JoinId` ) a");
query.ToList();
query = fsql.Select<Issues1510T1>()
.FromQuery(fsql.Select<Issues1510T2>().WithTempQuery(e => new { T2 = e }).WithTempQuery(e => e.T2))
.InnerJoin(t => t.t1.Id == t.t2.T1JoinId)
.WithTempQuery(t => new
{
t.t1.Id,
t.t1.Name,
T2Id = t.t2.Id,
T2Name = t.t1.Name,
});
sql = query.ToSql();
Assert.Equal(sql, @"SELECT *
FROM (
SELECT a.`Id`, a.`Name`, htb.`Id` `T2Id`, a.`Name` `T2Name`
FROM `Issues1510T1` a
INNER JOIN (
SELECT a.`Id`, a.`Name`, a.`T1JoinId`
FROM (
SELECT a.`Id`, a.`Name`, a.`T1JoinId`
FROM `Issues1510T2` a ) a ) htb ON a.`Id` = htb.`T1JoinId` ) a");
query.ToList();
//////////////////////////
var query2 = fsql.Select<Issues1510T1>()
.FromQuery(fsql.Select<Issues1510T2>().WithTempQuery(e => e))
.InnerJoin(t => t.t1.Id == t.t2.T1JoinId)
.WithTempQuery(t => new
{
T1Id = t.t1.Id,
T1Name = t.t1.Name,
T2Id = t.t2.Id,
T2Name = t.t1.Name,
});
sql = query2.ToSql();
Assert.Equal(sql, @"SELECT *
FROM (
SELECT a.`Id` `T1Id`, a.`Name` `T1Name`, htb.`Id` `T2Id`, a.`Name` `T2Name`
FROM `Issues1510T1` a
INNER JOIN (
SELECT a.`Id`, a.`Name`, a.`T1JoinId`
FROM `Issues1510T2` a ) htb ON a.`Id` = htb.`T1JoinId` ) a");
query2.ToList();
query2 = fsql.Select<Issues1510T1>()
.FromQuery(fsql.Select<Issues1510T2>().WithTempQuery(e => new { T2 = e }).WithTempQuery(e => e.T2))
.InnerJoin(t => t.t1.Id == t.t2.T1JoinId)
.WithTempQuery(t => new
{
T1Id = t.t1.Id,
T1Name = t.t1.Name,
T2Id = t.t2.Id,
T2Name = t.t1.Name,
});
sql = query2.ToSql();
Assert.Equal(sql, @"SELECT *
FROM (
SELECT a.`Id` `T1Id`, a.`Name` `T1Name`, htb.`Id` `T2Id`, a.`Name` `T2Name`
FROM `Issues1510T1` a
INNER JOIN (
SELECT a.`Id`, a.`Name`, a.`T1JoinId`
FROM (
SELECT a.`Id`, a.`Name`, a.`T1JoinId`
FROM `Issues1510T2` a ) a ) htb ON a.`Id` = htb.`T1JoinId` ) a");
query2.ToList();
query2 = fsql.Select<Issues1510T1>()
.WithTempQuery(e => e)
.FromQuery(fsql.Select<Issues1510T2>())
.InnerJoin(t => t.t1.Id == t.t2.T1JoinId)
.WithTempQuery(t => new
{
T1Id = t.t1.Id,
T1Name = t.t1.Name,
T2Id = t.t2.Id,
T2Name = t.t1.Name,
});
sql = query2.ToSql();
Assert.Equal(sql, @"SELECT *
FROM (
SELECT a.`Id` `T1Id`, a.`Name` `T1Name`, htb.`Id` `T2Id`, a.`Name` `T2Name`
FROM (
SELECT a.`Id`, a.`Name`
FROM `Issues1510T1` a ) a
INNER JOIN `Issues1510T2` htb ON a.`Id` = htb.`T1JoinId` ) a");
query2.ToList();
query2 = fsql.Select<Issues1510T1>()
.WithTempQuery(e => e)
.FromQuery(fsql.Select<Issues1510T2>().WithTempQuery(e => e))
.InnerJoin(t => t.t1.Id == t.t2.T1JoinId)
.WithTempQuery(t => new
{
T1Id = t.t1.Id,
T1Name = t.t1.Name,
T2Id = t.t2.Id,
T2Name = t.t1.Name,
});
sql = query2.ToSql();
Assert.Equal(sql, @"SELECT *
FROM (
SELECT a.`Id` `T1Id`, a.`Name` `T1Name`, htb.`Id` `T2Id`, a.`Name` `T2Name`
FROM (
SELECT a.`Id`, a.`Name`
FROM `Issues1510T1` a ) a
INNER JOIN (
SELECT a.`Id`, a.`Name`, a.`T1JoinId`
FROM `Issues1510T2` a ) htb ON a.`Id` = htb.`T1JoinId` ) a");
query2.ToList();
}
public class Issues1510T1
{
public long Id { get; set; }
public string Name { get; set; }
}
public class Issues1510T2
{
public long Id { get; set; }
public string Name { get; set; }
public long T1JoinId { get; set; }
}
[Fact] [Fact]
public void Issues1467() public void Issues1467()
{ {

View File

@ -0,0 +1,88 @@
<Playlist Version="2.0">
<Rule Name="Includes" Match="Any">
<Rule Match="All">
<Property Name="Solution" />
<Rule Match="Any">
<Rule Match="All">
<Property Name="Project" Value="FreeSql.Tests" />
<Rule Match="Any">
<Property Name="Namespace" Value="FreeSql.ExpressionTree" />
<Property Name="Namespace" Value="FreeSql.InternalTests" />
<Property Name="Namespace" Value="FreeSql.Tests" />
<Property Name="Namespace" Value="FreeSql.Tests.AdoNetExtensions.MySqlConnectionExtensions" />
<Property Name="Namespace" Value="FreeSql.Tests.AdoNetExtensions.NpgsqlConnectionExtensions" />
<Property Name="Namespace" Value="FreeSql.Tests.AdoNetExtensions.OracleConnectionExtensions" />
<Property Name="Namespace" Value="FreeSql.Tests.AdoNetExtensions.SqlConnectionExtensions" />
<Property Name="Namespace" Value="FreeSql.Tests.AdoNetExtensions.SQLiteConnectionExtensions" />
<Property Name="Namespace" Value="FreeSql.Tests.Dameng" />
<Property Name="Namespace" Value="FreeSql.Tests.DamengExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.DamengMapType" />
<Property Name="Namespace" Value="FreeSql.Tests.DataAnnotations" />
<Property Name="Namespace" Value="FreeSql.Tests.DynamicEntity" />
<Property Name="Namespace" Value="FreeSql.Tests.Extensions" />
<Property Name="Namespace" Value="FreeSql.Tests.Firebird" />
<Property Name="Namespace" Value="FreeSql.Tests.FirebirdExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.FirebirdMapType" />
<Property Name="Namespace" Value="FreeSql.Tests.Internal" />
<Property Name="Namespace" Value="FreeSql.Tests.Issues" />
<Property Name="Namespace" Value="FreeSql.Tests.Linq" />
<Property Name="Namespace" Value="FreeSql.Tests.MsAccess" />
<Property Name="Namespace" Value="FreeSql.Tests.MsAccessExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.MsAccessMapType" />
<Property Name="Namespace" Value="FreeSql.Tests.MySql" />
<Property Name="Namespace" Value="FreeSql.Tests.MySqlExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.MySqlMapType" />
<Property Name="Namespace" Value="FreeSql.Tests.Oracle" />
<Property Name="Namespace" Value="FreeSql.Tests.OracleExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.OracleMapType" />
<Property Name="Namespace" Value="FreeSql.Tests.PostgreSQL" />
<Property Name="Namespace" Value="FreeSql.Tests.PostgreSQL.PgArrayToMany" />
<Property Name="Namespace" Value="FreeSql.Tests.PostgreSQLExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.PostgreSQLMapType" />
<Property Name="Namespace" Value="FreeSql.Tests.Properties" />
<Property Name="Namespace" Value="FreeSql.Tests.Sqlite" />
<Property Name="Namespace" Value="FreeSql.Tests.SqliteExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.SqliteMapType" />
<Property Name="Namespace" Value="FreeSql.Tests.SqlServer" />
<Property Name="Namespace" Value="FreeSql.Tests.SqlServerExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.SqlServerMapType" />
</Rule>
</Rule>
<Property Name="Project" Value="FreeSql.Tests.DbContext" />
<Property Name="Project" Value="FreeSql.Tests.PerformanceTests" />
<Property Name="Project" Value="FreeSql.Tests.Provider.Custom" />
<Property Name="Project" Value="FreeSql.Tests.Provider.MySqlConnector (net6.0)" />
<Property Name="Project" Value="FreeSql.Tests.Provider.MySqlConnector (netcoreapp3.1)" />
<Rule Match="All">
<Property Name="Project" Value="FreeSql.Tests.Provider.Odbc" />
<Rule Match="Any">
<Property Name="Namespace" Value="FreeSql.Tests.Odbc" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.Dameng" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.DamengExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.DamengMapType" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.Default" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.DefaultExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.DefaultMapType" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.MySql" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.MySqlExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.MySqlMapType" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.Oracle" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.OracleExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.OracleMapType" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.PostgreSQL" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.PostgreSQLExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.PostgreSQLMapType" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.SqlServer" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.SqlServerExpression" />
<Property Name="Namespace" Value="FreeSql.Tests.Odbc.SqlServerMapType" />
</Rule>
</Rule>
<Property Name="Project" Value="FreeSql.Tests.Provider.OracleOledb (net6.0)" />
<Property Name="Project" Value="FreeSql.Tests.Provider.OracleOledb (netcoreapp3.1)" />
<Property Name="Project" Value="FreeSql.Tests.Provider.PostgreSQL.NetTopologySuite" />
<Property Name="Project" Value="FreeSql.Tests.Provider.Sqlite.Data" />
<Property Name="Project" Value="FreeSql.Tests.VB" />
</Rule>
</Rule>
</Rule>
</Playlist>

View File

@ -123,6 +123,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.Aggregat
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.Xugu", "Providers\FreeSql.Provider.Xugu\FreeSql.Provider.Xugu.csproj", "{8064870C-22EA-4A58-972D-DBD57D096D91}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.Xugu", "Providers\FreeSql.Provider.Xugu\FreeSql.Provider.Xugu.csproj", "{8064870C-22EA-4A58-972D-DBD57D096D91}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.Xugu", "FreeSql.Tests\FreeSql.Tests.Provider.Xugu\FreeSql.Tests.Provider.Xugu.csproj", "{16C21D77-20AC-4722-AD97-F53BDDE8210C}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -733,6 +735,18 @@ Global
{8064870C-22EA-4A58-972D-DBD57D096D91}.Release|x64.Build.0 = Release|Any CPU {8064870C-22EA-4A58-972D-DBD57D096D91}.Release|x64.Build.0 = Release|Any CPU
{8064870C-22EA-4A58-972D-DBD57D096D91}.Release|x86.ActiveCfg = Release|Any CPU {8064870C-22EA-4A58-972D-DBD57D096D91}.Release|x86.ActiveCfg = Release|Any CPU
{8064870C-22EA-4A58-972D-DBD57D096D91}.Release|x86.Build.0 = Release|Any CPU {8064870C-22EA-4A58-972D-DBD57D096D91}.Release|x86.Build.0 = Release|Any CPU
{16C21D77-20AC-4722-AD97-F53BDDE8210C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16C21D77-20AC-4722-AD97-F53BDDE8210C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16C21D77-20AC-4722-AD97-F53BDDE8210C}.Debug|x64.ActiveCfg = Debug|Any CPU
{16C21D77-20AC-4722-AD97-F53BDDE8210C}.Debug|x64.Build.0 = Debug|Any CPU
{16C21D77-20AC-4722-AD97-F53BDDE8210C}.Debug|x86.ActiveCfg = Debug|Any CPU
{16C21D77-20AC-4722-AD97-F53BDDE8210C}.Debug|x86.Build.0 = Debug|Any CPU
{16C21D77-20AC-4722-AD97-F53BDDE8210C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16C21D77-20AC-4722-AD97-F53BDDE8210C}.Release|Any CPU.Build.0 = Release|Any CPU
{16C21D77-20AC-4722-AD97-F53BDDE8210C}.Release|x64.ActiveCfg = Release|Any CPU
{16C21D77-20AC-4722-AD97-F53BDDE8210C}.Release|x64.Build.0 = Release|Any CPU
{16C21D77-20AC-4722-AD97-F53BDDE8210C}.Release|x86.ActiveCfg = Release|Any CPU
{16C21D77-20AC-4722-AD97-F53BDDE8210C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -775,8 +789,8 @@ Global
{8064870C-22EA-4A58-972D-DBD57D096D91} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {8064870C-22EA-4A58-972D-DBD57D096D91} = {2A381C57-2697-427B-9F10-55DA11FD02E4}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98}
RESX_PrefixTranslations = True
RESX_NeutralResourcesLanguage = en-US RESX_NeutralResourcesLanguage = en-US
RESX_PrefixTranslations = True
SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@ -40,8 +40,9 @@ namespace FreeSql
if (providerType == null) throw new Exception(CoreStrings.Missing_FreeSqlProvider_Package("Oracle")); if (providerType == null) throw new Exception(CoreStrings.Missing_FreeSqlProvider_Package("Oracle"));
break; break;
case "SQLiteConnection": case "SQLiteConnection":
case "SqliteConnection":
providerType = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(connType); providerType = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(connType);
if (providerType == null) throw new Exception(CoreStrings.Missing_FreeSqlProvider_Package("Sqlite")); if (providerType == null) throw new Exception(CoreStrings.Missing_FreeSqlProvider_Package("Sqlite/SqliteCore"));
break; break;
case "DmConnection": case "DmConnection":
providerType = Type.GetType("FreeSql.Dameng.DamengProvider`1,FreeSql.Provider.Dameng")?.MakeGenericType(connType); providerType = Type.GetType("FreeSql.Dameng.DamengProvider`1,FreeSql.Provider.Dameng")?.MakeGenericType(connType);
@ -423,4 +424,4 @@ namespace FreeSql
#endregion #endregion
} }
} }

View File

@ -0,0 +1,458 @@
// by: Daily
#if net40 || NETSTANDARD2_0
#else
using FreeSql;
using FreeSql.DataAnnotations;
using FreeSql.Extensions.DynamicEntity;
using FreeSql.Internal.CommonProvider;
using FreeSql.Internal.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Serialization;
public static class FreeSqlGlobalDynamicEntityExtensions
{
/// <summary>
/// 动态构建Class Type
/// </summary>
/// <returns></returns>
public static DynamicCompileBuilder DynamicEntity(this ICodeFirst codeFirst, string className,
params Attribute[] attributes)
{
return new DynamicCompileBuilder((codeFirst as CodeFirstProvider)._orm, className, attributes);
}
/// <summary>
/// 根据字典,创建 table 对应的实体对象
/// </summary>
/// <param name="table"></param>
/// <param name="dict"></param>
/// <returns></returns>
public static object CreateInstance(this TableInfo table, Dictionary<string, object> dict)
{
if (table == null || dict == null) return null;
var instance = table.Type.CreateInstanceGetDefaultValue();
//加载默认值
var defaultValueInit = table.Type.GetMethod("DefaultValueInit");
if (defaultValueInit != null)
{
defaultValueInit.Invoke(instance, new object[0]);
}
foreach (var key in table.ColumnsByCs.Keys)
{
if (dict.ContainsKey(key) == false) continue;
table.ColumnsByCs[key].SetValue(instance, dict[key]);
}
return instance;
}
/// <summary>
/// 根据实体对象,创建 table 对应的字典
/// </summary>
/// <param name="table"></param>
/// <param name="instance"></param>
/// <returns></returns>
public static Dictionary<string, object> CreateDictionary(this TableInfo table, object instance)
{
if (table == null || instance == null) return null;
var dict = new Dictionary<string, object>();
foreach (var key in table.ColumnsByCs.Keys)
dict[key] = table.ColumnsByCs[key].GetValue(instance);
return dict;
}
}
namespace FreeSql.Extensions.DynamicEntity
{
/// <summary>
/// 动态创建实体类型
/// </summary>
public class DynamicCompileBuilder
{
private string _className = string.Empty;
private Attribute[] _tableAttributes = null;
private List<DynamicPropertyInfo> _properties = new List<DynamicPropertyInfo>();
private Type _superClass = null;
private IFreeSql _fsql = null;
/// <summary>
/// 配置Class
/// </summary>
/// <param name="className">类名</param>
/// <param name="attributes">类标记的特性[Table(Name = "xxx")] [Index(xxxx)]</param>
/// <returns></returns>
public DynamicCompileBuilder(IFreeSql fsql, string className, params Attribute[] attributes)
{
_fsql = fsql;
_className = className;
_tableAttributes = attributes;
}
/// <summary>
/// 配置属性
/// </summary>
/// <param name="propertyName">属性名称</param>
/// <param name="propertyType">属性类型</param>
/// <param name="attributes">属性标记的特性-支持多个</param>
/// <returns></returns>
public DynamicCompileBuilder Property(string propertyName, Type propertyType,
params Attribute[] attributes)
{
_properties.Add(new DynamicPropertyInfo()
{
PropertyName = propertyName,
PropertyType = propertyType,
DefaultValue = null,
Attributes = attributes
});
return this;
}
/// <summary>
/// 配置属性
/// </summary>
/// <param name="propertyName">属性名称</param>
/// <param name="propertyType">属性类型</param>
/// <param name="isOverride">该属性是否重写父类属性</param>
/// <param name="attributes">属性标记的特性-支持多个</param>
/// <returns></returns>
public DynamicCompileBuilder Property(string propertyName, Type propertyType, bool isOverride,
params Attribute[] attributes)
{
_properties.Add(new DynamicPropertyInfo()
{
PropertyName = propertyName,
PropertyType = propertyType,
DefaultValue = null,
IsOverride = isOverride,
Attributes = attributes
});
return this;
}
/// <summary>
/// 配置属性
/// </summary>
/// <param name="propertyName">属性名称</param>
/// <param name="propertyType">属性类型</param>
/// <param name="isOverride">该属性是否重写父类属性</param>
/// <param name="defaultValue">属性默认值</param>
/// <param name="attributes">属性标记的特性-支持多个</param>
/// <returns></returns>
public DynamicCompileBuilder Property(string propertyName, Type propertyType, bool isOverride,
object defaultValue, params Attribute[] attributes)
{
_properties.Add(new DynamicPropertyInfo()
{
PropertyName = propertyName,
PropertyType = propertyType,
DefaultValue = defaultValue,
IsOverride = isOverride,
Attributes = attributes
});
return this;
}
/// <summary>
/// 配置父类
/// </summary>
/// <param name="superClass">父类类型</param>
/// <returns></returns>
public DynamicCompileBuilder Extend(Type superClass)
{
_superClass = superClass;
return this;
}
private void SetTableAttribute(ref TypeBuilder typeBuilder)
{
if (_tableAttributes == null) return;
foreach (var tableAttribute in _tableAttributes)
{
var propertyValues = new ArrayList();
if (tableAttribute == null) continue;
var classCtorInfo = tableAttribute.GetType().GetConstructor(Type.EmptyTypes);
var propertyInfos = tableAttribute.GetType().GetProperties().Where(p => p.CanWrite == true).ToArray();
foreach (var propertyInfo in propertyInfos)
propertyValues.Add(propertyInfo.GetValue(tableAttribute));
//可能存在有参构造
if (classCtorInfo == null)
{
var constructorTypes = propertyInfos.Select(p => p.PropertyType);
classCtorInfo = tableAttribute.GetType().GetConstructor(constructorTypes.ToArray());
var customAttributeBuilder = new CustomAttributeBuilder(classCtorInfo, propertyValues.ToArray());
typeBuilder.SetCustomAttribute(customAttributeBuilder);
}
else
{
var customAttributeBuilder = new CustomAttributeBuilder(classCtorInfo, new object[0], propertyInfos,
propertyValues.ToArray());
typeBuilder.SetCustomAttribute(customAttributeBuilder);
}
}
}
private void SetPropertys(ref TypeBuilder typeBuilder)
{
var defaultValues = new Dictionary<FieldBuilder, object>();
foreach (var pinfo in _properties)
{
if (pinfo == null)
continue;
var propertyName = pinfo.PropertyName;
var propertyType = pinfo.PropertyType;
//设置字段
var field = typeBuilder.DefineField($"_{FirstCharToLower(propertyName)}", propertyType,
FieldAttributes.Private | FieldAttributes.HasDefault);
var firstCharToUpper = FirstCharToUpper(propertyName);
MethodAttributes maAttributes = MethodAttributes.Public;
//是否重写
if (pinfo.IsOverride)
{
maAttributes = MethodAttributes.Public | MethodAttributes.Virtual;
}
//设置属性方法
var methodGet = typeBuilder.DefineMethod($"get_{firstCharToUpper}", maAttributes, propertyType, null);
var methodSet = typeBuilder.DefineMethod($"set_{firstCharToUpper}", maAttributes, null,
new Type[] { propertyType });
var ilOfGet = methodGet.GetILGenerator();
ilOfGet.Emit(OpCodes.Ldarg_0);
ilOfGet.Emit(OpCodes.Ldfld, field);
ilOfGet.Emit(OpCodes.Ret);
var ilOfSet = methodSet.GetILGenerator();
ilOfSet.Emit(OpCodes.Ldarg_0);
ilOfSet.Emit(OpCodes.Ldarg_1);
ilOfSet.Emit(OpCodes.Stfld, field);
ilOfSet.Emit(OpCodes.Ret);
//是否重写
if (pinfo.IsOverride)
{
//重写Get、Set方法
OverrideProperty(ref typeBuilder, methodGet, PropertyMethodEnum.GET, pinfo.PropertyName);
OverrideProperty(ref typeBuilder, methodSet, PropertyMethodEnum.SET, pinfo.PropertyName);
}
//设置属性
var propertyBuilder =
typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, propertyType, null);
propertyBuilder.SetGetMethod(methodGet);
propertyBuilder.SetSetMethod(methodSet);
foreach (var pinfoAttribute in pinfo.Attributes)
{
//设置特性
SetPropertyAttribute(ref propertyBuilder, pinfoAttribute);
}
if (pinfo.DefaultValue != null)
{
defaultValues.Add(field, pinfo.DefaultValue);
}
}
//动态构建方法,设置默认值
var methodDefaultValue = typeBuilder.DefineMethod($"DefaultValueInit", MethodAttributes.Public, null, null);
var methodDefaultValueLlGenerator = methodDefaultValue.GetILGenerator();
foreach (var kv in defaultValues)
{
methodDefaultValueLlGenerator.Emit(OpCodes.Ldarg_0);
OpCodesAdapter(ref methodDefaultValueLlGenerator, kv.Key, kv.Value);
methodDefaultValueLlGenerator.Emit(OpCodes.Stfld, kv.Key);
}
methodDefaultValueLlGenerator.Emit(OpCodes.Ret);
}
//IL命令类型适配
private void OpCodesAdapter(ref ILGenerator generator, FieldInfo info, object value)
{
var fieldTypeName = info.FieldType.Name;
switch (fieldTypeName)
{
case "Int32":
generator.Emit(OpCodes.Ldc_I4, Convert.ToInt32(value));
break;
case "Boolean":
generator.Emit(OpCodes.Ldc_I4, Convert.ToInt32(value));
break;
case "Char":
generator.Emit(OpCodes.Ldc_I4, Convert.ToChar(value));
break;
case "String":
generator.Emit(OpCodes.Ldstr, Convert.ToString(value));
break;
case "DateTime":
generator.Emit(OpCodes.Ldstr, Convert.ToString(value));
generator.Emit(OpCodes.Call, typeof(DateTime).GetMethod("Parse", new[] { typeof(string) }));
break;
case "Int64":
generator.Emit(OpCodes.Ldc_I4, Convert.ToString(value));
generator.Emit(OpCodes.Conv_I8);
break;
case "Double":
generator.Emit(OpCodes.Ldc_R8, Convert.ToDouble(value));
break;
case "Single":
generator.Emit(OpCodes.Ldc_R4, Convert.ToSingle(value));
break;
case "Decimal":
Console.WriteLine(Convert.ToString(value));
generator.Emit(OpCodes.Ldstr, Convert.ToString(value));
generator.Emit(OpCodes.Call, typeof(Decimal).GetMethod("Parse", new[] { typeof(string) }));
break;
}
}
private void SetPropertyAttribute<T>(ref PropertyBuilder propertyBuilder, T tAttribute)
{
if (tAttribute == null) return;
var propertyInfos = tAttribute.GetType().GetProperties().Where(p => p.CanWrite == true).ToArray();
var constructor = tAttribute.GetType().GetConstructor(Type.EmptyTypes);
var propertyValues = new ArrayList();
foreach (var propertyInfo in propertyInfos)
propertyValues.Add(propertyInfo.GetValue(tAttribute));
//可能存在有参构造
//if (constructor == null)
//{
// var constructorTypes = propertyInfos.Select(p => p.PropertyType).ToList();
// constructor = tAttribute.GetType().GetConstructor(constructorTypes.ToArray());
// var customAttributeBuilder = new CustomAttributeBuilder(constructor, constructorTypes.ToArray(),
// propertyInfos, propertyValues.ToArray());
// propertyBuilder.SetCustomAttribute(customAttributeBuilder);
//}
//else
//{
var customAttributeBuilder = new CustomAttributeBuilder(constructor, new object[0], propertyInfos,
propertyValues.ToArray());
propertyBuilder.SetCustomAttribute(customAttributeBuilder);
// }
}
/// <summary>
/// Override属性
/// </summary>
/// <param name="typeBuilder"></param>
private void OverrideProperty(ref TypeBuilder typeBuilder, MethodBuilder methodBuilder,
PropertyMethodEnum methodEnum,
string propertyName)
{
//查找父类的属性信息
var propertyInfo = typeBuilder.BaseType.GetProperty(propertyName);
if (propertyInfo == null) return;
var pm = methodEnum == PropertyMethodEnum.GET ? propertyInfo.GetGetMethod() : propertyInfo.GetSetMethod();
//重写父类GET SET 方法
typeBuilder.DefineMethodOverride(methodBuilder, pm);
}
/// <summary>
/// Emit动态创建出Class - Type
/// </summary>
/// <returns></returns>
public TableInfo Build()
{
//初始化AssemblyName的一个实例
var assemblyName = new AssemblyName("FreeSql.DynamicCompileBuilder");
//设置程序集的名称
var defineDynamicAssembly = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
//动态在程序集内创建一个模块
var defineDynamicModule =
defineDynamicAssembly.DefineDynamicModule("FreeSql.DynamicCompileBuilder.Dynamics");
//动态的在模块内创建一个类
var typeBuilder =
defineDynamicModule.DefineType(_className, TypeAttributes.Public | TypeAttributes.Class, _superClass);
//设置TableAttribute
SetTableAttribute(ref typeBuilder);
//设置属性
SetPropertys(ref typeBuilder);
//创建类的Type对象
var type = typeBuilder.CreateType();
return _fsql.CodeFirst.GetTableByEntity(type);
}
/// <summary>
/// 首字母小写
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private string FirstCharToLower(string input)
{
if (string.IsNullOrEmpty(input))
return input;
string str = input.First().ToString().ToLower() + input.Substring(1);
return str;
}
/// <summary>
/// 首字母大写
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private string FirstCharToUpper(string input)
{
if (string.IsNullOrEmpty(input))
return input;
string str = input.First().ToString().ToUpper() + input.Substring(1);
return str;
}
private static string Md5Encryption(string inputStr)
{
var result = string.Empty;
//32位大写
using (var md5 = MD5.Create())
{
var resultBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(inputStr));
result = BitConverter.ToString(resultBytes);
}
return result;
}
class DynamicPropertyInfo
{
public string PropertyName { get; set; } = string.Empty;
public Type PropertyType { get; set; }
public object DefaultValue { get; set; }
public bool IsOverride { get; set; } = false;
public Attribute[] Attributes { get; set; }
}
enum PropertyMethodEnum
{
GET,
SET
}
}
}
#endif

View File

@ -188,6 +188,17 @@ namespace FreeSql
expContext.Value.Result = $"{expContext.Value.ParsedContent["value1"]} <= {expContext.Value.ParsedContent["value2"]}"; expContext.Value.Result = $"{expContext.Value.ParsedContent["value1"]} <= {expContext.Value.ParsedContent["value2"]}";
return false; return false;
} }
/// <summary>
/// value1 IS NULL
/// </summary>
/// <typeparam name="TValue"></typeparam>
/// <param name="value1"></param>
/// <returns></returns>
public static bool EqualIsNull<TValue>(TValue value1)
{
expContext.Value.Result = $"{expContext.Value.ParsedContent["value1"]} IS NULL";
return false;
}
#endregion #endregion
/// <summary> /// <summary>

View File

@ -1,5 +1,6 @@
using FreeSql; using FreeSql;
using FreeSql.DataAnnotations; using FreeSql.DataAnnotations;
using FreeSql.Internal;
using FreeSql.Internal.CommonProvider; using FreeSql.Internal.CommonProvider;
using FreeSql.Internal.Model; using FreeSql.Internal.Model;
using FreeSql.Internal.ObjectPool; using FreeSql.Internal.ObjectPool;
@ -137,8 +138,27 @@ public static partial class FreeSqlGlobalExtensions
.Append(string.Join(", ", genericParameters.Select(a => a.DisplayCsharp()))) .Append(string.Join(", ", genericParameters.Select(a => a.DisplayCsharp())))
.Append('>'); .Append('>');
sb.Append('(').Append(string.Join(", ", method.GetParameters().Select(a => $"{a.ParameterType.DisplayCsharp()} {a.Name}"))).Append(')'); sb.Append("(").Append(string.Join(", ", method.GetParameters().Select(a => LocalDisplayCsharpParameter(a)))).Append(")");
return sb.ToString(); return sb.ToString();
string LocalDisplayCsharpParameter(ParameterInfo lp)
{
var pstr = "";
object[] pattrs = new object[0];
try { pattrs = lp.GetCustomAttributes(false); } catch { }
if (pattrs.Any(a => a is ParamArrayAttribute)) pstr = "params ";
pstr = $"{pstr}{lp.ParameterType.DisplayCsharp()} {lp.Name}";
#if net40
if (pattrs.Any(a => a is System.Runtime.InteropServices.OptionalAttribute) == false) return pstr;
#else
if (lp.HasDefaultValue == false) return pstr;
#endif
if (lp.DefaultValue == null) return $"{pstr} = null";
if (lp.ParameterType == typeof(string)) return $"{pstr} = \"{lp.DefaultValue.ToString().Replace("\"", "\\\"").Replace("\r\n", "\\r\\n").Replace("\n", "\\n")}\"";
if (lp.ParameterType == typeof(bool) || lp.ParameterType == typeof(bool?)) return $"{pstr} = {lp.DefaultValue.ToString().Replace("False", "false").Replace("True", "true")}";
if (lp.ParameterType.IsEnum) return $"{pstr} = {lp.ParameterType.DisplayCsharp(false)}.{lp.DefaultValue}";
return $"{pstr} = {lp.DefaultValue}";
}
} }
public static object CreateInstanceGetDefaultValue(this Type that) public static object CreateInstanceGetDefaultValue(this Type that)
{ {
@ -1311,4 +1331,5 @@ SELECT ");
return NativeTuple.Create(query, af, sql); return NativeTuple.Create(query, af, sql);
} }
#endregion #endregion
} }

View File

@ -17,7 +17,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -1073,6 +1073,82 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="T:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder">
<summary>
动态创建实体类型
</summary>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.#ctor(IFreeSql,System.String,System.Attribute[])">
<summary>
配置Class
</summary>
<param name="className">类名</param>
<param name="attributes">类标记的特性[Table(Name = "xxx")] [Index(xxxx)]</param>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Property(System.String,System.Type,System.Attribute[])">
<summary>
配置属性
</summary>
<param name="propertyName">属性名称</param>
<param name="propertyType">属性类型</param>
<param name="attributes">属性标记的特性-支持多个</param>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Property(System.String,System.Type,System.Boolean,System.Attribute[])">
<summary>
配置属性
</summary>
<param name="propertyName">属性名称</param>
<param name="propertyType">属性类型</param>
<param name="isOverride">该属性是否重写父类属性</param>
<param name="attributes">属性标记的特性-支持多个</param>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Property(System.String,System.Type,System.Boolean,System.Object,System.Attribute[])">
<summary>
配置属性
</summary>
<param name="propertyName">属性名称</param>
<param name="propertyType">属性类型</param>
<param name="isOverride">该属性是否重写父类属性</param>
<param name="defaultValue">属性默认值</param>
<param name="attributes">属性标记的特性-支持多个</param>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Extend(System.Type)">
<summary>
配置父类
</summary>
<param name="superClass">父类类型</param>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.OverrideProperty(System.Reflection.Emit.TypeBuilder@,System.Reflection.Emit.MethodBuilder,FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.PropertyMethodEnum,System.String)">
<summary>
Override属性
</summary>
<param name="typeBuilder"></param>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Build">
<summary>
Emit动态创建出Class - Type
</summary>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.FirstCharToLower(System.String)">
<summary>
首字母小写
</summary>
<param name="input"></param>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.FirstCharToUpper(System.String)">
<summary>
首字母大写
</summary>
<param name="input"></param>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetEntityKeyString(IFreeSql,System.Type,System.Object,System.Boolean,System.String)"> <member name="M:FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetEntityKeyString(IFreeSql,System.Type,System.Object,System.Boolean,System.String)">
<summary> <summary>
获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null
@ -1301,6 +1377,14 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:FreeSql.SqlExt.EqualIsNull``1(``0)">
<summary>
value1 IS NULL
</summary>
<typeparam name="TValue"></typeparam>
<param name="value1"></param>
<returns></returns>
</member>
<member name="M:FreeSql.SqlExt.Case"> <member name="M:FreeSql.SqlExt.Case">
<summary> <summary>
case when .. then .. end case when .. then .. end
@ -1837,6 +1921,16 @@
<param name="columns">属性名,或者字段名</param> <param name="columns">属性名,或者字段名</param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:FreeSql.IInsertOrUpdate`1.UpdateSet``1(System.Linq.Expressions.Expression{System.Func{`0,`0,``0}})">
<summary>
设置列的联表值,格式:<para></para>
UpdateSet((a, b) => a.Clicks == b.xxx)<para></para>
UpdateSet((a, b) => a.Clicks == a.Clicks + 1)
</summary>
<typeparam name="TMember"></typeparam>
<param name="exp"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IInsertOrUpdate`1.AsTable(System.Func{System.String,System.String})"> <member name="M:FreeSql.IInsertOrUpdate`1.AsTable(System.Func{System.String,System.String})">
<summary> <summary>
设置表名规则,可用于分库/分表参数1默认表名返回值新表名 设置表名规则,可用于分库/分表参数1默认表名返回值新表名
@ -5692,6 +5786,28 @@
请使用 fsql.InsertDict(dict) 方法插入字典数据 请使用 fsql.InsertDict(dict) 方法插入字典数据
</summary> </summary>
</member> </member>
<member name="M:FreeSqlGlobalDynamicEntityExtensions.DynamicEntity(FreeSql.ICodeFirst,System.String,System.Attribute[])">
<summary>
动态构建Class Type
</summary>
<returns></returns>
</member>
<member name="M:FreeSqlGlobalDynamicEntityExtensions.CreateInstance(FreeSql.Internal.Model.TableInfo,System.Collections.Generic.Dictionary{System.String,System.Object})">
<summary>
根据字典,创建 table 对应的实体对象
</summary>
<param name="table"></param>
<param name="dict"></param>
<returns></returns>
</member>
<member name="M:FreeSqlGlobalDynamicEntityExtensions.CreateDictionary(FreeSql.Internal.Model.TableInfo,System.Object)">
<summary>
根据实体对象,创建 table 对应的字典
</summary>
<param name="table"></param>
<param name="instance"></param>
<returns></returns>
</member>
<member name="M:FreeSqlGlobalExpressionCallExtensions.Between(System.DateTime,System.DateTime,System.DateTime)"> <member name="M:FreeSqlGlobalExpressionCallExtensions.Between(System.DateTime,System.DateTime,System.DateTime)">
<summary> <summary>
C# that >= between &amp;&amp; that &lt;= and<para></para> C# that >= between &amp;&amp; that &lt;= and<para></para>

View File

@ -86,6 +86,16 @@ namespace FreeSql
/// <returns></returns> /// <returns></returns>
IInsertOrUpdate<T1> UpdateColumns(string[] columns); IInsertOrUpdate<T1> UpdateColumns(string[] columns);
/// <summary>
/// 设置列的联表值,格式:<para></para>
/// UpdateSet((a, b) => a.Clicks == b.xxx)<para></para>
/// UpdateSet((a, b) => a.Clicks == a.Clicks + 1)
/// </summary>
/// <typeparam name="TMember"></typeparam>
/// <param name="exp"></param>
/// <returns></returns>
IInsertOrUpdate<T1> UpdateSet<TMember>(Expression<Func<T1, T1, TMember>> exp);
/// <summary> /// <summary>
/// 设置表名规则,可用于分库/分表参数1默认表名返回值新表名 /// 设置表名规则,可用于分库/分表参数1默认表名返回值新表名
/// </summary> /// </summary>

View File

@ -71,7 +71,16 @@ namespace FreeSql.Internal
field.Append(_common.FieldAsAlias(parent.DbNestedField)); field.Append(_common.FieldAsAlias(parent.DbNestedField));
} }
else if (isdiymemexp && diymemexp?.ParseExpMapResult != null) else if (isdiymemexp && diymemexp?.ParseExpMapResult != null)
{
parent.DbNestedField = diymemexp.ParseExpMapResult.DbNestedField; parent.DbNestedField = diymemexp.ParseExpMapResult.DbNestedField;
if (EndsWithDbNestedField(parent.DbField, $" {parent.DbNestedField}") == false && //#1510 group by 产生的 DbField 自带 alias因此需要此行判断
string.IsNullOrEmpty(parent.CsName) == false && localIndex == ReadAnonymousFieldAsCsName)
{
parent.DbNestedField = GetFieldAsCsName(parent.CsName);
if (EndsWithDbNestedField(parent.DbField, parent.DbNestedField) == false) //DbField 和 CsName 相同的时候,不处理
field.Append(_common.FieldAsAlias(parent.DbNestedField));
}
}
else if (string.IsNullOrEmpty(parent.CsName) == false) else if (string.IsNullOrEmpty(parent.CsName) == false)
{ {
parent.DbNestedField = GetFieldAsCsName(parent.CsName); parent.DbNestedField = GetFieldAsCsName(parent.CsName);
@ -1739,7 +1748,7 @@ namespace FreeSql.Internal
if (oper2.NodeType == ExpressionType.Parameter) if (oper2.NodeType == ExpressionType.Parameter)
{ {
var oper2Parm = oper2 as ParameterExpression; var oper2Parm = oper2 as ParameterExpression;
if (exp2.Type.IsAbstract || exp2.Type.IsInterface || exp2.Type.IsAssignableFrom(oper2Parm.Type)) if (oper2Parm.Type != typeof(object) && (exp2.Type.IsAbstract || exp2.Type.IsInterface || exp2.Type.IsAssignableFrom(oper2Parm.Type)))
expStack.Push(oper2Parm); expStack.Push(oper2Parm);
else if (oper2Parm.Type != typeof(object) && oper2Parm.Type.IsAssignableFrom(exp2.Type)) else if (oper2Parm.Type != typeof(object) && oper2Parm.Type.IsAssignableFrom(exp2.Type))
expStack.Push(oper2Parm); expStack.Push(oper2Parm);

View File

@ -196,8 +196,9 @@ namespace FreeSql.Internal.CommonProvider
} }
var sb = new StringBuilder(); var sb = new StringBuilder();
if (_table.AsTableImpl != null) if (_table.AsTableImpl != null && string.IsNullOrWhiteSpace(_tableRule?.Invoke(_table.DbName)) == true)
{ {
var oldTableRule = _tableRule;
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils); var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils);
foreach (var name in names) foreach (var name in names)
{ {
@ -206,6 +207,7 @@ namespace FreeSql.Internal.CommonProvider
_interceptSql?.Invoke(sb); _interceptSql?.Invoke(sb);
fetch(sb); fetch(sb);
} }
_tableRule = oldTableRule;
return; return;
} }
@ -229,8 +231,9 @@ namespace FreeSql.Internal.CommonProvider
} }
var sb = new StringBuilder(); var sb = new StringBuilder();
if (_table.AsTableImpl != null) if (_table.AsTableImpl != null && string.IsNullOrWhiteSpace(_tableRule?.Invoke(_table.DbName)) == true)
{ {
var oldTableRule = _tableRule;
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils); var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils);
foreach (var name in names) foreach (var name in names)
{ {
@ -239,6 +242,7 @@ namespace FreeSql.Internal.CommonProvider
_interceptSql?.Invoke(sb); _interceptSql?.Invoke(sb);
await fetchAsync(sb); await fetchAsync(sb);
} }
_tableRule = oldTableRule;
return; return;
} }

View File

@ -23,6 +23,7 @@ namespace FreeSql.Internal.CommonProvider
public bool _doNothing = false; public bool _doNothing = false;
public Dictionary<string, bool> _updateIgnore = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase); public Dictionary<string, bool> _updateIgnore = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
public Dictionary<string, bool> _auditValueChangedDict = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase); public Dictionary<string, bool> _auditValueChangedDict = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
public Dictionary<string, string> _updateSetDict = new Dictionary<string, string>();
public TableInfo _table; public TableInfo _table;
public ColumnInfo[] _tempPrimarys; public ColumnInfo[] _tempPrimarys;
public Func<string, string> _tableRule; public Func<string, string> _tableRule;
@ -87,6 +88,55 @@ namespace FreeSql.Internal.CommonProvider
return this; return this;
} }
public IInsertOrUpdate<T1> UpdateSet<TMember>(Expression<Func<T1, T1, TMember>> exp)
{
var body = exp?.Body;
var nodeType = body?.NodeType;
if (nodeType == ExpressionType.Convert)
{
body = (body as UnaryExpression)?.Operand;
nodeType = body?.NodeType;
}
switch (nodeType)
{
case ExpressionType.Equal:
break;
default:
throw new Exception("格式错了,请使用 .Set((a,b) => a.name == b.xname)");
}
var equalBinaryExp = body as BinaryExpression;
var cols = new List<SelectColumnInfo>();
_commonExpression.ExpressionSelectColumn_MemberAccess(null, null, cols, SelectTableInfoType.From, equalBinaryExp.Left, true, null);
if (cols.Count != 1) return this;
var col = cols[0].Column;
var valueSql = "";
if (equalBinaryExp.Right.IsParameter())
{
var tmpQuery = _orm.Select<T1, T1>();
var tmpQueryProvider = tmpQuery as Select0Provider;
tmpQueryProvider._tables[0].Alias = "t1";
tmpQueryProvider._tables[0].Parameter = exp.Parameters[0];
tmpQueryProvider._tables[1].Alias = "t2";
tmpQueryProvider._tables[1].Parameter = exp.Parameters[1];
var valueExp = Expression.Lambda<Func<T1, T1, object>>(Expression.Convert(equalBinaryExp.Right, typeof(object)), exp.Parameters);
tmpQuery.GroupBy(valueExp);
valueSql = tmpQueryProvider._groupby?.Remove(0, " \r\nGROUP BY ".Length);
}
else
{
valueSql = _commonExpression.ExpressionLambdaToSql(equalBinaryExp.Right, new CommonExpression.ExpTSC
{
isQuoteName = true,
mapType = equalBinaryExp.Right is BinaryExpression ? null : col.Attribute.MapType
});
}
if (string.IsNullOrEmpty(valueSql)) return this;
_updateSetDict[col.Attribute.Name] = valueSql;
return this;
}
public static void AuditDataValue(object sender, IEnumerable<T1> data, IFreeSql orm, TableInfo table, Dictionary<string, bool> changedDict) public static void AuditDataValue(object sender, IEnumerable<T1> data, IFreeSql orm, TableInfo table, Dictionary<string, bool> changedDict)
{ {
if (data?.Any() != true) return; if (data?.Any() != true) return;

View File

@ -342,6 +342,7 @@ namespace FreeSql.Internal.CommonProvider
[typeof(string)] = typeof(DbDataReader).GetMethod("GetString", new Type[] { typeof(int) }), [typeof(string)] = typeof(DbDataReader).GetMethod("GetString", new Type[] { typeof(int) }),
//[typeof(Guid)] = typeof(DbDataReader).GetMethod("GetGuid", new Type[] { typeof(int) }) 有些驱动不兼容 //[typeof(Guid)] = typeof(DbDataReader).GetMethod("GetGuid", new Type[] { typeof(int) }) 有些驱动不兼容
}; };
public static Dictionary<DataType, Dictionary<Type, MethodInfo>> _dicMethodDataReaderGetValueOverride = new Dictionary<DataType, Dictionary<Type, MethodInfo>>();
public static MethodInfo MethodStringContains = typeof(string).GetMethod("Contains", new[] { typeof(string) }); public static MethodInfo MethodStringContains = typeof(string).GetMethod("Contains", new[] { typeof(string) });
public static MethodInfo MethodStringStartsWith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) }); public static MethodInfo MethodStringStartsWith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });

View File

@ -744,8 +744,11 @@ namespace FreeSql.Internal.CommonProvider
_orm.Aop.AuditDataReaderHandler == null && _orm.Aop.AuditDataReaderHandler == null &&
_dicMethodDataReaderGetValue.TryGetValue(col.Attribute.MapType.NullableTypeOrThis(), out var drGetValueMethod)) _dicMethodDataReaderGetValue.TryGetValue(col.Attribute.MapType.NullableTypeOrThis(), out var drGetValueMethod))
{ {
if (_dicMethodDataReaderGetValueOverride.TryGetValue(_orm.Ado.DataType, out var drDictOverride) && drDictOverride.TryGetValue(col.Attribute.MapType.NullableTypeOrThis(), out var drDictOverrideGetValueMethod))
drGetValueMethod = drDictOverrideGetValueMethod;
Expression drvalExp = Expression.Call(rowExp, drGetValueMethod, Expression.Constant(colidx)); Expression drvalExp = Expression.Call(rowExp, drGetValueMethod, Expression.Constant(colidx));
if (col.CsType.IsNullableType()) drvalExp = Expression.Convert(drvalExp, col.CsType); if (col.CsType.IsNullableType() || drGetValueMethod.ReturnType != col.CsType) drvalExp = Expression.Convert(drvalExp, col.CsType);
drvalExp = Expression.Condition(Expression.Call(rowExp, _MethodDataReaderIsDBNull, Expression.Constant(colidx)), Expression.Default(col.CsType), drvalExp); drvalExp = Expression.Condition(Expression.Call(rowExp, _MethodDataReaderIsDBNull, Expression.Constant(colidx)), Expression.Default(col.CsType), drvalExp);
if (drvalType.IsArray || drvalType.IsEnum || Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(drvalType)) if (drvalType.IsArray || drvalType.IsEnum || Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(drvalType))

View File

@ -174,7 +174,7 @@ namespace FreeSql.Internal.CommonProvider
if (equalBinaryExp.Right.IsParameter()) if (equalBinaryExp.Right.IsParameter())
{ {
_query2Provider._groupby = null; _query2Provider._groupby = null;
var valueExp = Expression.Lambda<Func<T1, T2, object>>(equalBinaryExp.Right, exp.Parameters); var valueExp = Expression.Lambda<Func<T1, T2, object>>(Expression.Convert(equalBinaryExp.Right, typeof(object)), exp.Parameters);
_query2.GroupBy(valueExp); _query2.GroupBy(valueExp);
valueSql = _query2Provider._groupby?.Remove(0, " \r\nGROUP BY ".Length); valueSql = _query2Provider._groupby?.Remove(0, " \r\nGROUP BY ".Length);
} }

View File

@ -894,28 +894,32 @@ namespace FreeSql.Internal.CommonProvider
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = "); sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ");
string valsqlOld = null; var valsameIf = col.Attribute.MapType.IsNumberType() ||
var valsqlOldStats = 1; //start 1 new[] { typeof(string), typeof(DateTime), typeof(DateTime?) }.Contains(col.Attribute.MapType) ||
var nullStats = 0; col.Attribute.MapType.NullableTypeOrThis().IsEnum;
var cwsb = new StringBuilder().Append(cw); var ds = _source.Select(a => col.GetDbValue(a)).ToArray();
foreach (var d in _source) if (valsameIf && ds.All(a => object.Equals(a, ds[0])))
{ {
cwsb.Append(" \r\nWHEN "); var val = ds.First();
ToSqlWhen(cwsb, _tempPrimarys, d); var colsql = thenValue(_commonUtils.RewriteColumn(col, _commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col, col.Attribute.MapType, val)));
cwsb.Append(" THEN "); sb.Append(colsql);
var val = col.GetDbValue(d); }
var valsql = thenValue(_commonUtils.RewriteColumn(col, _commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col, col.Attribute.MapType, val))); else
cwsb.Append(valsql); {
if (valsqlOld == null) valsqlOld = valsql; var cwsb = new StringBuilder().Append(cw);
else if (valsqlOld == valsql) valsqlOldStats++; foreach (var d in _source)
if (val == null || val == DBNull.Value) nullStats++; {
cwsb.Append(" \r\nWHEN ");
ToSqlWhen(cwsb, _tempPrimarys, d);
cwsb.Append(" THEN ");
var val = col.GetDbValue(d);
var colsql = thenValue(_commonUtils.RewriteColumn(col, _commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col, col.Attribute.MapType, val)));
cwsb.Append(colsql);
}
cwsb.Append(" END");
sb.Append(cwsb);
cwsb.Clear();
} }
cwsb.Append(" END");
if (nullStats == _source.Count) sb.Append("NULL");
else if (valsqlOldStats == _source.Count) sb.Append(valsqlOld);
else sb.Append(cwsb);
cwsb.Clear();
return sb.ToString(); return sb.ToString();
} }
} }
@ -1004,8 +1008,9 @@ namespace FreeSql.Internal.CommonProvider
ToSqlWhere(newwhere); ToSqlWhere(newwhere);
var sb = new StringBuilder(); var sb = new StringBuilder();
if (_table.AsTableImpl != null) if (_table.AsTableImpl != null && string.IsNullOrWhiteSpace(_tableRule?.Invoke(_table.DbName)) == true)
{ {
var oldTableRule = _tableRule;
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils); var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils);
foreach (var name in names) foreach (var name in names)
{ {
@ -1013,6 +1018,7 @@ namespace FreeSql.Internal.CommonProvider
ToSqlExtension110(sb.Clear(), true); ToSqlExtension110(sb.Clear(), true);
fetch(sb); fetch(sb);
} }
_tableRule = oldTableRule;
return; return;
} }
@ -1036,8 +1042,9 @@ namespace FreeSql.Internal.CommonProvider
ToSqlWhere(newwhere); ToSqlWhere(newwhere);
var sb = new StringBuilder(); var sb = new StringBuilder();
if (_table.AsTableImpl != null) if (_table.AsTableImpl != null && string.IsNullOrWhiteSpace(_tableRule?.Invoke(_table.DbName)) == true)
{ {
var oldTableRule = _tableRule;
var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils); var names = _table.AsTableImpl.GetTableNamesBySqlWhere(newwhere.ToString(), _params, new SelectTableInfo { Table = _table }, _commonUtils);
foreach (var name in names) foreach (var name in names)
{ {
@ -1045,6 +1052,7 @@ namespace FreeSql.Internal.CommonProvider
ToSqlExtension110(sb.Clear(), true); ToSqlExtension110(sb.Clear(), true);
await fetchAsync(sb); await fetchAsync(sb);
} }
_tableRule = oldTableRule;
return; return;
} }
@ -1143,30 +1151,41 @@ namespace FreeSql.Internal.CommonProvider
sb.Append(col.DbUpdateValue); sb.Append(col.DbUpdateValue);
else else
{ {
var nulls = 0; var valsameIf = col.Attribute.MapType.IsNumberType() ||
var cwsb = new StringBuilder().Append(cw); new[] { typeof(string), typeof(DateTime), typeof(DateTime?) }.Contains(col.Attribute.MapType) ||
foreach (var d in _source) col.Attribute.MapType.NullableTypeOrThis().IsEnum;
var ds = _source.Select(a => col.GetDbValue(a)).ToArray();
if (valsameIf && ds.All(a => object.Equals(a, ds[0])))
{ {
cwsb.Append(" \r\nWHEN "); var val = ds.First();
ToSqlWhen(cwsb, _tempPrimarys, d);
cwsb.Append(" THEN ");
var val = col.GetDbValue(d);
var colsql = _noneParameter ? _commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col, col.Attribute.MapType, val) : var colsql = _noneParameter ? _commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col, col.Attribute.MapType, val) :
_commonUtils.QuoteWriteParamterAdapter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}")); _commonUtils.QuoteWriteParamterAdapter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"));
cwsb.Append(_commonUtils.RewriteColumn(col, colsql)); sb.Append(_commonUtils.RewriteColumn(col, colsql));
if (_noneParameter == false) if (_noneParameter == false)
_commonUtils.AppendParamter(_paramsSource, null, col, col.Attribute.MapType, val); _commonUtils.AppendParamter(_paramsSource, null, col, col.Attribute.MapType, val);
if (val == null || val == DBNull.Value) nulls++;
} }
cwsb.Append(" END");
if (nulls == _source.Count) sb.Append("NULL");
else else
{ {
var cwsb = new StringBuilder().Append(cw);
foreach (var d in _source)
{
cwsb.Append(" \r\nWHEN ");
ToSqlWhen(cwsb, _tempPrimarys, d);
cwsb.Append(" THEN ");
var val = col.GetDbValue(d);
var colsql = _noneParameter ? _commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col, col.Attribute.MapType, val) :
_commonUtils.QuoteWriteParamterAdapter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"));
colsql = _commonUtils.RewriteColumn(col, colsql);
cwsb.Append(colsql);
if (_noneParameter == false)
_commonUtils.AppendParamter(_paramsSource, null, col, col.Attribute.MapType, val);
}
cwsb.Append(" END");
ToSqlCaseWhenEnd(cwsb, col); ToSqlCaseWhenEnd(cwsb, col);
sb.Append(cwsb); sb.Append(cwsb);
cwsb.Clear();
} }
cwsb.Clear();
} }
++colidx; ++colidx;
} }

View File

@ -50,9 +50,9 @@ namespace FreeSql.Internal.ObjectPool
{ {
public IPolicy<T> Policy { get; protected set; } public IPolicy<T> Policy { get; protected set; }
private List<Object<T>> _allObjects = new List<Object<T>>();
private object _allObjectsLock = new object(); private object _allObjectsLock = new object();
private ConcurrentStack<Object<T>> _freeObjects = new ConcurrentStack<Object<T>>(); internal List<Object<T>> _allObjects = new List<Object<T>>();
internal ConcurrentStack<Object<T>> _freeObjects = new ConcurrentStack<Object<T>>();
private ConcurrentQueue<GetSyncQueueInfo> _getSyncQueue = new ConcurrentQueue<GetSyncQueueInfo>(); private ConcurrentQueue<GetSyncQueueInfo> _getSyncQueue = new ConcurrentQueue<GetSyncQueueInfo>();
private ConcurrentQueue<TaskCompletionSource<Object<T>>> _getAsyncQueue = new ConcurrentQueue<TaskCompletionSource<Object<T>>>(); private ConcurrentQueue<TaskCompletionSource<Object<T>>> _getAsyncQueue = new ConcurrentQueue<TaskCompletionSource<Object<T>>>();
@ -112,8 +112,8 @@ namespace FreeSql.Internal.ObjectPool
try try
{ {
var conn = GetFree(false); var conn = GetFree(false);
if (conn == null) throw new Exception(CoreStrings.Available_Failed_Get_Resource("CheckAvailable", this.Statistics)); if (conn == null) throw new Exception($"【{Policy.Name}】Failed to get resource {this.Statistics}");
try try
{ {
try try
@ -125,7 +125,7 @@ namespace FreeSql.Internal.ObjectPool
{ {
conn.ResetValue(); conn.ResetValue();
} }
if (Policy.OnCheckAvailable(conn) == false) throw new Exception(CoreStrings.Available_Thrown_Exception("CheckAvailable")); if (Policy.OnCheckAvailable(conn) == false) throw new Exception("【{Policy.Name}】An exception needs to be thrown");
break; break;
} }
finally finally
@ -177,11 +177,11 @@ namespace FreeSql.Internal.ObjectPool
try try
{ {
var conn = GetFree(false); var conn = GetFree(false);
if (conn == null) throw new Exception(CoreStrings.Available_Failed_Get_Resource("LiveCheckAvailable", this.Statistics)); if (conn == null) throw new Exception($"【{Policy.Name}】Failed to get resource {this.Statistics}");
try try
{ {
if (Policy.OnCheckAvailable(conn) == false) throw new Exception(CoreStrings.Available_Thrown_Exception("LiveCheckAvailable")); if (Policy.OnCheckAvailable(conn) == false) throw new Exception("【{Policy.Name}】An exception needs to be thrown");
} }
finally finally
{ {
@ -281,10 +281,10 @@ namespace FreeSql.Internal.ObjectPool
{ {
if (running == false) if (running == false)
throw new ObjectDisposedException(CoreStrings.Policy_ObjectPool_Dispose(Policy.Name)); throw new ObjectDisposedException($"【{Policy.Name}】The ObjectPool has been disposed, see: https://github.com/dotnetcore/FreeSql/discussions/1079");
if (checkAvailable && UnavailableException != null) if (checkAvailable && UnavailableException != null)
throw new Exception(CoreStrings.Policy_Status_NotAvailable(Policy.Name,UnavailableException?.Message), UnavailableException); throw new Exception($"【{Policy.Name}】Status unavailable, waiting for recovery. {UnavailableException?.Message}", UnavailableException);
if ((_freeObjects.TryPop(out var obj) == false || obj == null) && _allObjects.Count < Policy.PoolSize) if ((_freeObjects.TryPop(out var obj) == false || obj == null) && _allObjects.Count < Policy.PoolSize)
{ {
@ -335,12 +335,13 @@ namespace FreeSql.Internal.ObjectPool
if (obj == null) obj = queueItem.ReturnValue; if (obj == null) obj = queueItem.ReturnValue;
if (obj == null) lock (queueItem.Lock) queueItem.IsTimeout = (obj = queueItem.ReturnValue) == null; if (obj == null) lock (queueItem.Lock) queueItem.IsTimeout = (obj = queueItem.ReturnValue) == null;
if (obj == null) obj = queueItem.ReturnValue; if (obj == null) obj = queueItem.ReturnValue;
if (queueItem.Exception != null) throw queueItem.Exception;
if (obj == null) if (obj == null)
{ {
Policy.OnGetTimeout(); Policy.OnGetTimeout();
if (Policy.IsThrowGetTimeoutException) if (Policy.IsThrowGetTimeoutException)
throw new TimeoutException(CoreStrings.ObjectPool_Get_Timeout(Policy.Name, "Get", timeout.Value.TotalSeconds)); throw new TimeoutException($"【{Policy.Name}】ObjectPool.Get() timeout {timeout.Value.TotalSeconds} seconds, see: https://github.com/dotnetcore/FreeSql/discussions/1081");
return null; return null;
} }
@ -372,7 +373,7 @@ namespace FreeSql.Internal.ObjectPool
if (obj == null) if (obj == null)
{ {
if (Policy.AsyncGetCapacity > 0 && _getAsyncQueue.Count >= Policy.AsyncGetCapacity - 1) if (Policy.AsyncGetCapacity > 0 && _getAsyncQueue.Count >= Policy.AsyncGetCapacity - 1)
throw new OutOfMemoryException(CoreStrings.ObjectPool_GetAsync_Queue_Long(Policy.Name, Policy.AsyncGetCapacity)); throw new OutOfMemoryException($"【{Policy.Name}】ObjectPool.GetAsync() The queue is too long. Policy. AsyncGetCapacity = {Policy.AsyncGetCapacity}");
var tcs = new TaskCompletionSource<Object<T>>(); var tcs = new TaskCompletionSource<Object<T>>();
@ -392,7 +393,7 @@ namespace FreeSql.Internal.ObjectPool
// Policy.GetTimeout(); // Policy.GetTimeout();
// if (Policy.IsThrowGetTimeoutException) // if (Policy.IsThrowGetTimeoutException)
// throw new Exception($"ObjectPool.GetAsync 获取超时({timeout.Value.TotalSeconds}秒)。"); // throw new TimeoutException($"【{Policy.Name}】ObjectPool.GetAsync() timeout {timeout.Value.TotalSeconds} seconds, see: https://github.com/dotnetcore/FreeSql/discussions/1081");
// return null; // return null;
//} //}
@ -444,16 +445,26 @@ namespace FreeSql.Internal.ObjectPool
if (queueItem.ReturnValue != null) if (queueItem.ReturnValue != null)
{ {
obj.LastReturnThreadId = Thread.CurrentThread.ManagedThreadId; if (UnavailableException != null)
obj.LastReturnTime = DateTime.Now;
try
{ {
queueItem.Wait.Set(); queueItem.Exception = new Exception($"【{Policy.Name}】Status unavailable, waiting for recovery. {UnavailableException?.Message}", UnavailableException);
isReturn = true; try
{
queueItem.Wait.Set();
}
catch { }
} }
catch else
{ {
obj.LastReturnThreadId = Thread.CurrentThread.ManagedThreadId;
obj.LastReturnTime = DateTime.Now;
try
{
queueItem.Wait.Set();
isReturn = true;
}
catch { }
} }
} }
@ -464,10 +475,25 @@ namespace FreeSql.Internal.ObjectPool
{ {
if (_getAsyncQueue.TryDequeue(out var tcs) && tcs != null && tcs.Task.IsCanceled == false) if (_getAsyncQueue.TryDequeue(out var tcs) && tcs != null && tcs.Task.IsCanceled == false)
{ {
obj.LastReturnThreadId = Thread.CurrentThread.ManagedThreadId; if (UnavailableException != null)
obj.LastReturnTime = DateTime.Now; {
try
{
tcs.TrySetException(new Exception($"【{Policy.Name}】Status unavailable, waiting for recovery. {UnavailableException?.Message}", UnavailableException));
}
catch { }
}
else
{
obj.LastReturnThreadId = Thread.CurrentThread.ManagedThreadId;
obj.LastReturnTime = DateTime.Now;
try { isReturn = tcs.TrySetResult(obj); } catch { } try
{
isReturn = tcs.TrySetResult(obj);
}
catch { }
}
} }
} }
} }
@ -524,6 +550,7 @@ namespace FreeSql.Internal.ObjectPool
internal Object<T> ReturnValue { get; set; } internal Object<T> ReturnValue { get; set; }
internal object Lock = new object(); internal object Lock = new object();
internal bool IsTimeout { get; set; } = false; internal bool IsTimeout { get; set; } = false;
internal Exception Exception { get; set; }
public void Dispose() public void Dispose()
{ {

View File

@ -481,7 +481,22 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname);
{ {
cmd.CommandText = sql; cmd.CommandText = sql;
cmd.CommandType = CommandType.Text; cmd.CommandType = CommandType.Text;
return cmd.ExecuteScalar(); var before = new Aop.CommandBeforeEventArgs(cmd);
this._orm?.Aop.CommandBeforeHandler?.Invoke(this._orm, before);
Exception afterException = null;
try
{
return cmd.ExecuteScalar();
}
catch (Exception ex)
{
afterException = ex;
throw;
}
finally
{
this._orm?.Aop.CommandAfterHandler?.Invoke(this._orm, new Aop.CommandAfterEventArgs(before, afterException, null));
}
} }
} }
finally finally

View File

@ -19,7 +19,7 @@
<SignAssembly>False</SignAssembly> <SignAssembly>False</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@ -32,7 +32,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="ClickHouse.Client"> <PackageReference Include="ClickHouse.Client">
<Version>4.0.1.462</Version> <Version>6.6.0</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
namespace FreeSql.Custom.MySql namespace FreeSql.Custom.MySql
{ {
@ -62,10 +63,26 @@ namespace FreeSql.Custom.MySql
insert.InsertIdentity(); insert.InsertIdentity();
if (_doNothing == false) if (_doNothing == false)
{ {
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
sql = new CustomMySqlOnDuplicateKeyUpdate<T1>(insert) sql = new CustomMySqlOnDuplicateKeyUpdate<T1>(insert)
.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()) .UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray())
.ToSql(); .ToSql();
if (_updateSetDict.Any())
{
var findregex = new Regex("(t1|t2)." + _commonUtils.QuoteSqlName("test").Replace("test", "(\\w+)"));
foreach (var usd in _updateSetDict)
{
var field = _commonUtils.QuoteSqlName(usd.Key);
var findsql = $"{field} = VALUES({field})";
var usdval = findregex.Replace(usd.Value, m =>
{
if (m.Groups[1].Value == "t1") return _commonUtils.QuoteSqlName(m.Groups[2].Value);
return $"VALUES({_commonUtils.QuoteSqlName(m.Groups[2].Value)})";
});
sql = sql.Replace(findsql, $"{field} = {usdval}");
}
}
} }
else else
{ {

View File

@ -382,7 +382,22 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI
{ {
cmd.CommandText = sql; cmd.CommandText = sql;
cmd.CommandType = CommandType.Text; cmd.CommandType = CommandType.Text;
return cmd.ExecuteScalar(); var before = new Aop.CommandBeforeEventArgs(cmd);
this._orm?.Aop.CommandBeforeHandler?.Invoke(this._orm, before);
Exception afterException = null;
try
{
return cmd.ExecuteScalar();
}
catch (Exception ex)
{
afterException = ex;
throw;
}
finally
{
this._orm?.Aop.CommandAfterHandler?.Invoke(this._orm, new Aop.CommandAfterEventArgs(before, afterException, null));
}
} }
} }
finally finally

View File

@ -39,14 +39,18 @@ namespace FreeSql.Custom.Oracle
WriteSourceSelectUnionAll(data, sb, dbParams); WriteSourceSelectUnionAll(data, sb, dbParams);
sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n");
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
if (_doNothing == false && cols.Any()) if (_doNothing == false && cols.Any())
sb.Append("WHEN MATCHED THEN \r\n") sb.Append("WHEN MATCHED THEN \r\n")
.Append(" update set ").Append(string.Join(", ", cols.Select(a => .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? {
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : if (_updateSetDict.TryGetValue(a.Attribute.Name, out var valsql))
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}" return $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = {valsql}";
))).Append(" \r\n"); return a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ?
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}";
}))).Append(" \r\n");
cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true);
if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false); if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false);

View File

@ -32,11 +32,15 @@ namespace FreeSql.Custom.Oracle
sbunion.Append(_select); sbunion.Append(_select);
if (_distinct) sbunion.Append("DISTINCT "); if (_distinct) sbunion.Append("DISTINCT ");
sbunion.Append(field);
if (string.IsNullOrEmpty(_orderby) && _skip > 0) sbunion.Append(", ROWNUM AS \"__rownum__\"");
sbunion.Append(" \r\nFROM ");
var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray();
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
var isRownum = string.IsNullOrEmpty(_orderby) && _skip > 0;
if (isRownum && field == "*") sbunion.Append(tbsfrom[0].Alias).Append("."); //#1519 bug
sbunion.Append(field);
if (isRownum) sbunion.Append(", ROWNUM AS \"__rownum__\"");
sbunion.Append(" \r\nFROM ");
for (var a = 0; a < tbsfrom.Length; a++) for (var a = 0; a < tbsfrom.Length; a++)
{ {
sbunion.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); sbunion.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias);

View File

@ -463,6 +463,12 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam
else if (sqlType.StartsWith("NCLOB")) else if (sqlType.StartsWith("NCLOB"))
{ {
} }
else if (sqlType.StartsWith("RAW"))
{
}
else if (sqlType.StartsWith("LONG RAW"))
{
}
else if (char_used.ToLower() == "c") else if (char_used.ToLower() == "c")
sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)"; sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)";
else if (char_used.ToLower() == "b") else if (char_used.ToLower() == "b")

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
namespace FreeSql.Custom.PostgreSQL namespace FreeSql.Custom.PostgreSQL
{ {
@ -57,11 +58,29 @@ namespace FreeSql.Custom.PostgreSQL
{ {
var ocdu = new CustomPostgreSQLOnConflictDoUpdate<T1>(insert.InsertIdentity()); var ocdu = new CustomPostgreSQLOnConflictDoUpdate<T1>(insert.InsertIdentity());
ocdu._tempPrimarys = _tempPrimarys; ocdu._tempPrimarys = _tempPrimarys;
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray());
if (_doNothing == true || cols.Any() == false) if (_doNothing == true || cols.Any() == false)
ocdu.DoNothing(); ocdu.DoNothing();
sql = ocdu.ToSql(); sql = ocdu.ToSql();
if (_updateSetDict.Any())
{
var findregex = new Regex("(t1|t2)." + _commonUtils.QuoteSqlName("test").Replace("test", "(\\w+)"));
var tableName = _commonUtils.QuoteSqlName(TableRuleInvoke());
foreach (var usd in _updateSetDict)
{
var field = _commonUtils.QuoteSqlName(usd.Key);
var findsql = $"{field} = EXCLUDED.{field}";
var usdval = findregex.Replace(usd.Value, m =>
{
if (m.Groups[1].Value == "t1") return $"{tableName}.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
return $"EXCLUDED.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
});
sql = sql.Replace(findsql, $"{field} = {usdval}");
}
}
} }
if (string.IsNullOrEmpty(sql)) return null; if (string.IsNullOrEmpty(sql)) return null;
if (insert._params?.Any() == true) dbParams.AddRange(insert._params); if (insert._params?.Any() == true) dbParams.AddRange(insert._params);

View File

@ -41,14 +41,18 @@ namespace FreeSql.Custom.SqlServer
WriteSourceSelectUnionAll(data, sb, dbParams); WriteSourceSelectUnionAll(data, sb, dbParams);
sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n");
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
if (_doNothing == false && cols.Any()) if (_doNothing == false && cols.Any())
sb.Append("WHEN MATCHED THEN \r\n") sb.Append("WHEN MATCHED THEN \r\n")
.Append(" update set ").Append(string.Join(", ", cols.Select(a => .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? {
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : if (_updateSetDict.TryGetValue(a.Attribute.Name, out var valsql))
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}" return $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = {valsql}";
))).Append(" \r\n"); return a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ?
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}";
}))).Append(" \r\n");
cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true);
if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false); if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false);

View File

@ -41,7 +41,7 @@ namespace FreeSql.Custom.SqlServer
if (_distinct) sb.Append("DISTINCT "); if (_distinct) sb.Append("DISTINCT ");
//if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); //TOP 会引发 __rownum__ 无序的问题 //if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); //TOP 会引发 __rownum__ 无序的问题
if (_skip <= 0 && _limit > 0) sb.Append("TOP ").Append(_limit).Append(" "); if (_skip <= 0 && _limit > 0) sb.Append("TOP ").Append(_limit).Append(" ");
sb.Append(field); var rownum = "";
if (_limit > 0 || _skip > 0) if (_limit > 0 || _skip > 0)
{ {
@ -57,11 +57,14 @@ namespace FreeSql.Custom.SqlServer
_orderby = _groupby.Replace("GROUP BY ", "ORDER BY "); _orderby = _groupby.Replace("GROUP BY ", "ORDER BY ");
} }
if (_skip > 0) // 注意这个判断,大于 0 才使用 ROW_NUMBER ,否则属于第一页直接使用 TOP if (_skip > 0) // 注意这个判断,大于 0 才使用 ROW_NUMBER ,否则属于第一页直接使用 TOP
sb.Append(", ROW_NUMBER() OVER(").Append(_orderby.Trim('\r', '\n', ' ')).Append(") AS __rownum__"); rownum = $", ROW_NUMBER() OVER({_orderby.Trim('\r', '\n', ' ')}) AS __rownum__";
} }
sb.Append(" \r\nFROM ");
var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray();
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
if (string.IsNullOrEmpty(rownum) == false && field == "*")
sb.Append(tbsfrom[0].Alias).Append("."); //#1519 bug
sb.Append(field).Append(rownum);
sb.Append(" \r\nFROM ");
for (var a = 0; a < tbsfrom.Length; a++) for (var a = 0; a < tbsfrom.Length; a++)
{ {
var alias = LocalGetTableAlias(tbsfrom[a].Table.Type, tbUnion[tbsfrom[a].Table.Type], tbsfrom[a].Alias, _aliasRule); var alias = LocalGetTableAlias(tbsfrom[a].Table.Type, tbUnion[tbsfrom[a].Table.Type], tbsfrom[a].Alias, _aliasRule);

View File

@ -474,7 +474,22 @@ use [" + database + "];", tboldname ?? tbname);
{ {
cmd.CommandText = sql; cmd.CommandText = sql;
cmd.CommandType = CommandType.Text; cmd.CommandType = CommandType.Text;
return cmd.ExecuteScalar(); var before = new Aop.CommandBeforeEventArgs(cmd);
this._orm?.Aop.CommandBeforeHandler?.Invoke(this._orm, before);
Exception afterException = null;
try
{
return cmd.ExecuteScalar();
}
catch (Exception ex)
{
afterException = ex;
throw;
}
finally
{
this._orm?.Aop.CommandAfterHandler?.Invoke(this._orm, new Aop.CommandAfterEventArgs(before, afterException, null));
}
} }
} }
finally finally

View File

@ -39,14 +39,18 @@ namespace FreeSql.Dameng.Curd
WriteSourceSelectUnionAll(data, sb, dbParams); WriteSourceSelectUnionAll(data, sb, dbParams);
sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n");
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
if (_doNothing == false && cols.Any()) if (_doNothing == false && cols.Any())
sb.Append("WHEN MATCHED THEN \r\n") sb.Append("WHEN MATCHED THEN \r\n")
.Append(" update set ").Append(string.Join(", ", cols.Select(a => .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? {
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : if (_updateSetDict.TryGetValue(a.Attribute.Name, out var valsql))
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}" return $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = {valsql}";
))).Append(" \r\n"); return a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ?
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}";
}))).Append(" \r\n");
cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true);
if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false); if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false);

View File

@ -32,11 +32,14 @@ namespace FreeSql.Dameng.Curd
sbunion.Append(_select); sbunion.Append(_select);
if (_distinct) sbunion.Append("DISTINCT "); if (_distinct) sbunion.Append("DISTINCT ");
sbunion.Append(field);
if (string.IsNullOrEmpty(_orderby) && _skip > 0) sbunion.Append(", ROWNUM AS \"__rownum__\"");
sbunion.Append(" \r\nFROM ");
var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray();
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
var isRownum = string.IsNullOrEmpty(_orderby) && _skip > 0;
if (isRownum && field == "*") sbunion.Append(tbsfrom[0].Alias).Append("."); //#1519 bug
sbunion.Append(field);
if (isRownum) sbunion.Append(", ROWNUM AS \"__rownum__\"");
sbunion.Append(" \r\nFROM ");
for (var a = 0; a < tbsfrom.Length; a++) for (var a = 0; a < tbsfrom.Length; a++)
{ {
sbunion.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); sbunion.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias);

View File

@ -466,6 +466,12 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and
else if (sqlType.StartsWith("NCLOB")) else if (sqlType.StartsWith("NCLOB"))
{ {
} }
else if (sqlType.StartsWith("RAW"))
{
}
else if (sqlType.StartsWith("LONG RAW"))
{
}
else if (sqlType.StartsWith("TEXT")) else if (sqlType.StartsWith("TEXT"))
{ {
} }

View File

@ -40,7 +40,7 @@ public static partial class FreeSqlDamengGlobalExtensions
var _table = upsert._table; var _table = upsert._table;
var _commonUtils = upsert._commonUtils; var _commonUtils = upsert._commonUtils;
var updateTableName = upsert._tableRule?.Invoke(_table.DbName) ?? _table.DbName; var updateTableName = upsert._tableRule?.Invoke(_table.DbName) ?? _table.DbName;
var tempTableName = $"Temp_{Guid.NewGuid().ToString("N").ToUpper().Substring(0, 24)}"; var tempTableName = $"TEMP_{Guid.NewGuid().ToString("N").ToUpper().Substring(0, 24)}";
if (upsert._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower(); if (upsert._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower();
if (upsert._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper(); if (upsert._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper();
if (upsert._connection == null && upsert._orm.Ado.TransactionCurrentThread != null) if (upsert._connection == null && upsert._orm.Ado.TransactionCurrentThread != null)
@ -88,7 +88,7 @@ public static partial class FreeSqlDamengGlobalExtensions
var _table = update._table; var _table = update._table;
var _commonUtils = update._commonUtils; var _commonUtils = update._commonUtils;
var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName; var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName;
var tempTableName = $"Temp_{Guid.NewGuid().ToString("N").ToUpper().Substring(0, 24)}"; var tempTableName = $"TEMP_{Guid.NewGuid().ToString("N").ToUpper().Substring(0, 24)}";
if (update._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower(); if (update._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower();
if (update._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper(); if (update._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper();
if (update._connection == null && update._orm.Ado.TransactionCurrentThread != null) if (update._connection == null && update._orm.Ado.TransactionCurrentThread != null)

View File

@ -15,7 +15,7 @@
<Title>$(AssemblyName)</Title> <Title>$(AssemblyName)</Title>
<IsPackable>true</IsPackable> <IsPackable>true</IsPackable>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo> <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -39,14 +39,18 @@ namespace FreeSql.Firebird.Curd
WriteSourceSelectUnionAll(data, sb, dbParams); WriteSourceSelectUnionAll(data, sb, dbParams);
sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n");
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
if (_doNothing == false && cols.Any()) if (_doNothing == false && cols.Any())
sb.Append("WHEN MATCHED THEN \r\n") sb.Append("WHEN MATCHED THEN \r\n")
.Append(" update set ").Append(string.Join(", ", cols.Select(a => .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? {
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : if (_updateSetDict.TryGetValue(a.Attribute.Name, out var valsql))
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}" return $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = {valsql}";
))).Append(" \r\n"); return a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ?
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}";
}))).Append(" \r\n");
cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true);
if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false); if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false);

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -39,14 +39,18 @@ namespace FreeSql.GBase.Curd
WriteSourceSelectUnionAll(data, sb, dbParams); WriteSourceSelectUnionAll(data, sb, dbParams);
sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n");
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
if (_doNothing == false && cols.Any()) if (_doNothing == false && cols.Any())
sb.Append("WHEN MATCHED THEN \r\n") sb.Append("WHEN MATCHED THEN \r\n")
.Append(" update set ").Append(string.Join(", ", cols.Select(a => .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? {
$"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : if (_updateSetDict.TryGetValue(a.Attribute.Name, out var valsql))
$"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}" return $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = {valsql}";
))).Append(" \r\n"); return a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ?
$"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
$"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}";
}))).Append(" \r\n");
cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true);
if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false); if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false);

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -187,7 +187,22 @@ namespace FreeSql.GBase
{ {
cmd.CommandText = sql; cmd.CommandText = sql;
cmd.CommandType = CommandType.Text; cmd.CommandType = CommandType.Text;
return cmd.ExecuteScalar(); var before = new Aop.CommandBeforeEventArgs(cmd);
this._orm?.Aop.CommandBeforeHandler?.Invoke(this._orm, before);
Exception afterException = null;
try
{
return cmd.ExecuteScalar();
}
catch (Exception ex)
{
afterException = ex;
throw;
}
finally
{
this._orm?.Aop.CommandAfterHandler?.Invoke(this._orm, new Aop.CommandAfterEventArgs(before, afterException, null));
}
} }
} }
finally finally

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
namespace FreeSql.KingbaseES namespace FreeSql.KingbaseES
{ {
@ -57,11 +58,29 @@ namespace FreeSql.KingbaseES
{ {
var ocdu = new KingbaseESOnConflictDoUpdate<T1>(insert.InsertIdentity()); var ocdu = new KingbaseESOnConflictDoUpdate<T1>(insert.InsertIdentity());
ocdu._tempPrimarys = _tempPrimarys; ocdu._tempPrimarys = _tempPrimarys;
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray());
if (_doNothing == true || cols.Any() == false) if (_doNothing == true || cols.Any() == false)
ocdu.DoNothing(); ocdu.DoNothing();
sql = ocdu.ToSql(); sql = ocdu.ToSql();
if (_updateSetDict.Any())
{
var findregex = new Regex("(t1|t2)." + _commonUtils.QuoteSqlName("test").Replace("test", "(\\w+)"));
var tableName = _commonUtils.QuoteSqlName(TableRuleInvoke());
foreach (var usd in _updateSetDict)
{
var field = _commonUtils.QuoteSqlName(usd.Key);
var findsql = $"{field} = EXCLUDED.{field}";
var usdval = findregex.Replace(usd.Value, m =>
{
if (m.Groups[1].Value == "t1") return $"{tableName}.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
return $"EXCLUDED.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
});
sql = sql.Replace(findsql, $"{field} = {usdval}");
}
}
} }
if (string.IsNullOrEmpty(sql)) return null; if (string.IsNullOrEmpty(sql)) return null;
if (insert._params?.Any() == true) dbParams.AddRange(insert._params); if (insert._params?.Any() == true) dbParams.AddRange(insert._params);

View File

@ -15,7 +15,7 @@
<Title>$(AssemblyName)</Title> <Title>$(AssemblyName)</Title>
<IsPackable>true</IsPackable> <IsPackable>true</IsPackable>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo> <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -41,7 +41,7 @@ public static partial class FreeSqlKingbaseESGlobalExtensions
var _table = upsert._table; var _table = upsert._table;
var _commonUtils = upsert._commonUtils; var _commonUtils = upsert._commonUtils;
var updateTableName = upsert._tableRule?.Invoke(_table.DbName) ?? _table.DbName; var updateTableName = upsert._tableRule?.Invoke(_table.DbName) ?? _table.DbName;
var tempTableName = $"Temp_{Guid.NewGuid().ToString("N")}"; var tempTableName = $"temp_{Guid.NewGuid().ToString("N")}";
if (upsert._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower(); if (upsert._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower();
if (upsert._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper(); if (upsert._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper();
if (upsert._connection == null && upsert._orm.Ado.TransactionCurrentThread != null) if (upsert._connection == null && upsert._orm.Ado.TransactionCurrentThread != null)
@ -86,7 +86,7 @@ public static partial class FreeSqlKingbaseESGlobalExtensions
var _table = update._table; var _table = update._table;
var _commonUtils = update._commonUtils; var _commonUtils = update._commonUtils;
var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName; var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName;
var tempTableName = $"Temp_{Guid.NewGuid().ToString("N")}"; var tempTableName = $"temp_{Guid.NewGuid().ToString("N")}";
if (update._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower(); if (update._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower();
if (update._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper(); if (update._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper();
if (update._connection == null && update._orm.Ado.TransactionCurrentThread != null) if (update._connection == null && update._orm.Ado.TransactionCurrentThread != null)

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
namespace FreeSql.MySql.Curd namespace FreeSql.MySql.Curd
{ {
@ -62,10 +63,26 @@ namespace FreeSql.MySql.Curd
insert.InsertIdentity(); insert.InsertIdentity();
if (_doNothing == false) if (_doNothing == false)
{ {
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
sql = new OnDuplicateKeyUpdate<T1>(insert) sql = new OnDuplicateKeyUpdate<T1>(insert)
.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()) .UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray())
.ToSql(); .ToSql();
if (_updateSetDict.Any())
{
var findregex = new Regex("(t1|t2)." + _commonUtils.QuoteSqlName("test").Replace("test", "(\\w+)"));
foreach (var usd in _updateSetDict)
{
var field = _commonUtils.QuoteSqlName(usd.Key);
var findsql = $"{field} = VALUES({field})";
var usdval = findregex.Replace(usd.Value, m =>
{
if (m.Groups[1].Value == "t1") return _commonUtils.QuoteSqlName(m.Groups[2].Value);
return $"VALUES({_commonUtils.QuoteSqlName(m.Groups[2].Value)})";
});
sql = sql.Replace(findsql, $"{field} = {usdval}");
}
}
} }
else else
{ {

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -393,7 +393,22 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI
{ {
cmd.CommandText = sql; cmd.CommandText = sql;
cmd.CommandType = CommandType.Text; cmd.CommandType = CommandType.Text;
return cmd.ExecuteScalar(); var before = new Aop.CommandBeforeEventArgs(cmd);
this._orm?.Aop.CommandBeforeHandler?.Invoke(this._orm, before);
Exception afterException = null;
try
{
return cmd.ExecuteScalar();
}
catch (Exception ex)
{
afterException = ex;
throw;
}
finally
{
this._orm?.Aop.CommandAfterHandler?.Invoke(this._orm, new Aop.CommandAfterEventArgs(before, afterException, null));
}
} }
} }
finally finally

View File

@ -2,8 +2,10 @@
using FreeSql.Internal.CommonProvider; using FreeSql.Internal.CommonProvider;
using FreeSql.MySql.Curd; using FreeSql.MySql.Curd;
using System; using System;
using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reflection;
using System.Threading; using System.Threading;
namespace FreeSql.MySql namespace FreeSql.MySql
@ -11,32 +13,37 @@ namespace FreeSql.MySql
public class MySqlProvider<TMark> : BaseDbProvider, IFreeSql<TMark> public class MySqlProvider<TMark> : BaseDbProvider, IFreeSql<TMark>
{ {
static MySqlProvider() static int _firstInit = 1;
static void InitInternal()
{ {
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPoint)] = true; if (Interlocked.Exchange(ref _firstInit, 0) == 1) //不能放在 static ctor .NetFramework 可能报初始化类型错误
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisLineString)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPolygon)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPoint)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiLineString)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPolygon)] = true;
var MethodMygisGeometryParse = typeof(MygisGeometry).GetMethod("Parse", new[] { typeof(string) });
Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) =>
{ {
switch (type.FullName) Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPoint)] = true;
{ Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisLineString)] = true;
case "MygisPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPoint))); Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisPolygon)] = true;
case "MygisLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisLineString))); Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPoint)] = true;
case "MygisPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPolygon))); Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiLineString)] = true;
case "MygisMultiPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPoint))); Utils.dicExecuteArrayRowReadClassOrTuple[typeof(MygisMultiPolygon)] = true;
case "MygisMultiLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiLineString)));
case "MygisMultiPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPolygon)));
}
return null;
});
Select0Provider._dicMethodDataReaderGetValue[typeof(Guid)] = typeof(DbDataReader).GetMethod("GetGuid", new Type[] { typeof(int) }); var MethodMygisGeometryParse = typeof(MygisGeometry).GetMethod("Parse", new[] { typeof(string) });
Select0Provider._dicMethodDataReaderGetValue[typeof(DateTimeOffset)] = typeof(DbDataReader).GetMethod("GetDateTime", new Type[] { typeof(int) }); Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) =>
{
switch (type.FullName)
{
case "MygisPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPoint)));
case "MygisLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisLineString)));
case "MygisPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPolygon)));
case "MygisMultiPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPoint)));
case "MygisMultiLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiLineString)));
case "MygisMultiPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisMultiPolygon)));
}
return null;
});
Select0Provider._dicMethodDataReaderGetValueOverride[DataType.MySql] = new Dictionary<Type, MethodInfo>();
Select0Provider._dicMethodDataReaderGetValueOverride[DataType.MySql][typeof(Guid)] = typeof(DbDataReader).GetMethod("GetGuid", new Type[] { typeof(int) });
Select0Provider._dicMethodDataReaderGetValueOverride[DataType.MySql][typeof(DateTimeOffset)] = typeof(DbDataReader).GetMethod("GetDateTime", new Type[] { typeof(int) });
}
} }
public override ISelect<T1> CreateSelectProvider<T1>(object dywhere) => new MySqlSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public override ISelect<T1> CreateSelectProvider<T1>(object dywhere) => new MySqlSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
@ -47,6 +54,7 @@ namespace FreeSql.MySql
public MySqlProvider(string masterConnectionString, string[] slaveConnectionString, Func<DbConnection> connectionFactory = null) public MySqlProvider(string masterConnectionString, string[] slaveConnectionString, Func<DbConnection> connectionFactory = null)
{ {
InitInternal();
this.InternalCommonUtils = new MySqlUtils(this); this.InternalCommonUtils = new MySqlUtils(this);
this.InternalCommonExpression = new MySqlExpression(this.InternalCommonUtils); this.InternalCommonExpression = new MySqlExpression(this.InternalCommonUtils);

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -39,7 +39,7 @@ public static class FreeSqlMySqlConnectorGlobalExtensions
var _table = upsert._table; var _table = upsert._table;
var _commonUtils = upsert._commonUtils; var _commonUtils = upsert._commonUtils;
var updateTableName = upsert._tableRule?.Invoke(_table.DbName) ?? _table.DbName; var updateTableName = upsert._tableRule?.Invoke(_table.DbName) ?? _table.DbName;
var tempTableName = $"Temp_{Guid.NewGuid().ToString("N")}"; var tempTableName = $"temp_{Guid.NewGuid().ToString("N")}";
if (upsert._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower(); if (upsert._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower();
if (upsert._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper(); if (upsert._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper();
if (upsert._connection == null && upsert._orm.Ado.TransactionCurrentThread != null) if (upsert._connection == null && upsert._orm.Ado.TransactionCurrentThread != null)
@ -90,7 +90,7 @@ public static class FreeSqlMySqlConnectorGlobalExtensions
var _table = update._table; var _table = update._table;
var _commonUtils = update._commonUtils; var _commonUtils = update._commonUtils;
var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName; var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName;
var tempTableName = $"Temp_{Guid.NewGuid().ToString("N")}"; var tempTableName = $"temp_{Guid.NewGuid().ToString("N")}";
if (update._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower(); if (update._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower();
if (update._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper(); if (update._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper();
if (update._connection == null && update._orm.Ado.TransactionCurrentThread != null) if (update._connection == null && update._orm.Ado.TransactionCurrentThread != null)

View File

@ -39,14 +39,18 @@ namespace FreeSql.Odbc.Dameng
WriteSourceSelectUnionAll(data, sb, dbParams); WriteSourceSelectUnionAll(data, sb, dbParams);
sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n");
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
if (_doNothing == false && cols.Any()) if (_doNothing == false && cols.Any())
sb.Append("WHEN MATCHED THEN \r\n") sb.Append("WHEN MATCHED THEN \r\n")
.Append(" update set ").Append(string.Join(", ", cols.Select(a => .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? {
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : if (_updateSetDict.TryGetValue(a.Attribute.Name, out var valsql))
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}" return $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = {valsql}";
))).Append(" \r\n"); return a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ?
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}";
}))).Append(" \r\n");
cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true);
if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false); if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false);

View File

@ -32,11 +32,14 @@ namespace FreeSql.Odbc.Dameng
sbunion.Append(_select); sbunion.Append(_select);
if (_distinct) sbunion.Append("DISTINCT "); if (_distinct) sbunion.Append("DISTINCT ");
sbunion.Append(field);
if (string.IsNullOrEmpty(_orderby) && _skip > 0) sbunion.Append(", ROWNUM AS \"__rownum__\"");
sbunion.Append(" \r\nFROM ");
var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray();
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
var isRownum = string.IsNullOrEmpty(_orderby) && _skip > 0;
if (isRownum && field == "*") sbunion.Append(tbsfrom[0].Alias).Append("."); //#1519 bug
sbunion.Append(field);
if (isRownum) sbunion.Append(", ROWNUM AS \"__rownum__\"");
sbunion.Append(" \r\nFROM ");
for (var a = 0; a < tbsfrom.Length; a++) for (var a = 0; a < tbsfrom.Length; a++)
{ {
sbunion.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); sbunion.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias);

View File

@ -461,6 +461,12 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and
else if (sqlType.StartsWith("BLOB")) else if (sqlType.StartsWith("BLOB"))
{ {
} }
else if (sqlType.StartsWith("RAW"))
{
}
else if (sqlType.StartsWith("LONG RAW"))
{
}
else if (sqlType == "REAL" || sqlType == "DOUBLE" || sqlType == "FLOAT") else if (sqlType == "REAL" || sqlType == "DOUBLE" || sqlType == "FLOAT")
{ {
} }

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
namespace FreeSql.Odbc.KingbaseES namespace FreeSql.Odbc.KingbaseES
{ {
@ -58,11 +59,29 @@ namespace FreeSql.Odbc.KingbaseES
{ {
var ocdu = new OdbcKingbaseESOnConflictDoUpdate<T1>(insert.InsertIdentity()); var ocdu = new OdbcKingbaseESOnConflictDoUpdate<T1>(insert.InsertIdentity());
ocdu._tempPrimarys = _tempPrimarys; ocdu._tempPrimarys = _tempPrimarys;
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray());
if (_doNothing == true || cols.Any() == false) if (_doNothing == true || cols.Any() == false)
ocdu.DoNothing(); ocdu.DoNothing();
sql = ocdu.ToSql(); sql = ocdu.ToSql();
if (_updateSetDict.Any())
{
var findregex = new Regex("(t1|t2)." + _commonUtils.QuoteSqlName("test").Replace("test", "(\\w+)"));
var tableName = _commonUtils.QuoteSqlName(TableRuleInvoke());
foreach (var usd in _updateSetDict)
{
var field = _commonUtils.QuoteSqlName(usd.Key);
var findsql = $"{field} = EXCLUDED.{field}";
var usdval = findregex.Replace(usd.Value, m =>
{
if (m.Groups[1].Value == "t1") return $"{tableName}.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
return $"EXCLUDED.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
});
sql = sql.Replace(findsql, $"{field} = {usdval}");
}
}
} }
if (string.IsNullOrEmpty(sql)) return null; if (string.IsNullOrEmpty(sql)) return null;
if (insert._params?.Any() == true) dbParams.AddRange(insert._params); if (insert._params?.Any() == true) dbParams.AddRange(insert._params);

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
namespace FreeSql.Odbc.MySql namespace FreeSql.Odbc.MySql
{ {
@ -62,10 +63,26 @@ namespace FreeSql.Odbc.MySql
insert.InsertIdentity(); insert.InsertIdentity();
if (_doNothing == false) if (_doNothing == false)
{ {
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
sql = new OdbcMySqlOnDuplicateKeyUpdate<T1>(insert) sql = new OdbcMySqlOnDuplicateKeyUpdate<T1>(insert)
.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()) .UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray())
.ToSql(); .ToSql();
if (_updateSetDict.Any())
{
var findregex = new Regex("(t1|t2)." + _commonUtils.QuoteSqlName("test").Replace("test", "(\\w+)"));
foreach (var usd in _updateSetDict)
{
var field = _commonUtils.QuoteSqlName(usd.Key);
var findsql = $"{field} = VALUES({field})";
var usdval = findregex.Replace(usd.Value, m =>
{
if (m.Groups[1].Value == "t1") return _commonUtils.QuoteSqlName(m.Groups[2].Value);
return $"VALUES({_commonUtils.QuoteSqlName(m.Groups[2].Value)})";
});
sql = sql.Replace(findsql, $"{field} = {usdval}");
}
}
} }
else else
{ {

View File

@ -383,7 +383,22 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI
{ {
cmd.CommandText = sql; cmd.CommandText = sql;
cmd.CommandType = CommandType.Text; cmd.CommandType = CommandType.Text;
return cmd.ExecuteScalar(); var before = new Aop.CommandBeforeEventArgs(cmd);
this._orm?.Aop.CommandBeforeHandler?.Invoke(this._orm, before);
Exception afterException = null;
try
{
return cmd.ExecuteScalar();
}
catch (Exception ex)
{
afterException = ex;
throw;
}
finally
{
this._orm?.Aop.CommandAfterHandler?.Invoke(this._orm, new Aop.CommandAfterEventArgs(before, afterException, null));
}
} }
} }
finally finally

View File

@ -39,14 +39,18 @@ namespace FreeSql.Odbc.Oracle
WriteSourceSelectUnionAll(data, sb, dbParams); WriteSourceSelectUnionAll(data, sb, dbParams);
sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n");
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
if (_doNothing == false && cols.Any()) if (_doNothing == false && cols.Any())
sb.Append("WHEN MATCHED THEN \r\n") sb.Append("WHEN MATCHED THEN \r\n")
.Append(" update set ").Append(string.Join(", ", cols.Select(a => .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? {
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : if (_updateSetDict.TryGetValue(a.Attribute.Name, out var valsql))
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}" return $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = {valsql}";
))).Append(" \r\n"); return a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ?
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}";
}))).Append(" \r\n");
cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true);
if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false); if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false);

View File

@ -32,11 +32,14 @@ namespace FreeSql.Odbc.Oracle
sbunion.Append(_select); sbunion.Append(_select);
if (_distinct) sbunion.Append("DISTINCT "); if (_distinct) sbunion.Append("DISTINCT ");
sbunion.Append(field);
if (string.IsNullOrEmpty(_orderby) && _skip > 0) sbunion.Append(", ROWNUM AS \"__rownum__\"");
sbunion.Append(" \r\nFROM ");
var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray();
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
var isRownum = string.IsNullOrEmpty(_orderby) && _skip > 0;
if (isRownum && field == "*") sbunion.Append(tbsfrom[0].Alias).Append("."); //#1519 bug
sbunion.Append(field);
if (isRownum) sbunion.Append(", ROWNUM AS \"__rownum__\"");
sbunion.Append(" \r\nFROM ");
for (var a = 0; a < tbsfrom.Length; a++) for (var a = 0; a < tbsfrom.Length; a++)
{ {
sbunion.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); sbunion.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias);

View File

@ -465,6 +465,12 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam
else if (sqlType.StartsWith("NCLOB")) else if (sqlType.StartsWith("NCLOB"))
{ {
} }
else if (sqlType.StartsWith("RAW"))
{
}
else if (sqlType.StartsWith("LONG RAW"))
{
}
else if (char_used.ToLower() == "c") else if (char_used.ToLower() == "c")
sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)"; sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)";
else if (char_used.ToLower() == "b") else if (char_used.ToLower() == "b")

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
namespace FreeSql.Odbc.PostgreSQL namespace FreeSql.Odbc.PostgreSQL
{ {
@ -57,11 +58,29 @@ namespace FreeSql.Odbc.PostgreSQL
{ {
var ocdu = new OdbcPostgreSQLOnConflictDoUpdate<T1>(insert.InsertIdentity()); var ocdu = new OdbcPostgreSQLOnConflictDoUpdate<T1>(insert.InsertIdentity());
ocdu._tempPrimarys = _tempPrimarys; ocdu._tempPrimarys = _tempPrimarys;
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray());
if (_doNothing == true || cols.Any() == false) if (_doNothing == true || cols.Any() == false)
ocdu.DoNothing(); ocdu.DoNothing();
sql = ocdu.ToSql(); sql = ocdu.ToSql();
if (_updateSetDict.Any())
{
var findregex = new Regex("(t1|t2)." + _commonUtils.QuoteSqlName("test").Replace("test", "(\\w+)"));
var tableName = _commonUtils.QuoteSqlName(TableRuleInvoke());
foreach (var usd in _updateSetDict)
{
var field = _commonUtils.QuoteSqlName(usd.Key);
var findsql = $"{field} = EXCLUDED.{field}";
var usdval = findregex.Replace(usd.Value, m =>
{
if (m.Groups[1].Value == "t1") return $"{tableName}.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
return $"EXCLUDED.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
});
sql = sql.Replace(findsql, $"{field} = {usdval}");
}
}
} }
if (string.IsNullOrEmpty(sql)) return null; if (string.IsNullOrEmpty(sql)) return null;
if (insert._params?.Any() == true) dbParams.AddRange(insert._params); if (insert._params?.Any() == true) dbParams.AddRange(insert._params);

View File

@ -41,14 +41,18 @@ namespace FreeSql.Odbc.SqlServer
WriteSourceSelectUnionAll(data, sb, dbParams); WriteSourceSelectUnionAll(data, sb, dbParams);
sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n");
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
if (_doNothing == false && cols.Any()) if (_doNothing == false && cols.Any())
sb.Append("WHEN MATCHED THEN \r\n") sb.Append("WHEN MATCHED THEN \r\n")
.Append(" update set ").Append(string.Join(", ", cols.Select(a => .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? {
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : if (_updateSetDict.TryGetValue(a.Attribute.Name, out var valsql))
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}" return $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = {valsql}";
))).Append(" \r\n"); return a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ?
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}";
}))).Append(" \r\n");
cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true);
if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false); if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false);

View File

@ -41,7 +41,7 @@ namespace FreeSql.Odbc.SqlServer
if (_distinct) sb.Append("DISTINCT "); if (_distinct) sb.Append("DISTINCT ");
//if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); //TOP 会引发 __rownum__ 无序的问题 //if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); //TOP 会引发 __rownum__ 无序的问题
if (_skip <= 0 && _limit > 0) sb.Append("TOP ").Append(_limit).Append(" "); if (_skip <= 0 && _limit > 0) sb.Append("TOP ").Append(_limit).Append(" ");
sb.Append(field); var rownum = "";
if (_limit > 0 || _skip > 0) if (_limit > 0 || _skip > 0)
{ {
@ -57,11 +57,14 @@ namespace FreeSql.Odbc.SqlServer
_orderby = _groupby.Replace("GROUP BY ", "ORDER BY "); _orderby = _groupby.Replace("GROUP BY ", "ORDER BY ");
} }
if (_skip > 0) // 注意这个判断,大于 0 才使用 ROW_NUMBER ,否则属于第一页直接使用 TOP if (_skip > 0) // 注意这个判断,大于 0 才使用 ROW_NUMBER ,否则属于第一页直接使用 TOP
sb.Append(", ROW_NUMBER() OVER(").Append(_orderby.Trim('\r', '\n', ' ')).Append(") AS __rownum__"); rownum = $", ROW_NUMBER() OVER({_orderby.Trim('\r', '\n', ' ')}) AS __rownum__";
} }
sb.Append(" \r\nFROM ");
var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray();
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
if (string.IsNullOrEmpty(rownum) == false && field == "*")
sb.Append(tbsfrom[0].Alias).Append("."); //#1519 bug
sb.Append(field).Append(rownum);
sb.Append(" \r\nFROM ");
for (var a = 0; a < tbsfrom.Length; a++) for (var a = 0; a < tbsfrom.Length; a++)
{ {
var alias = LocalGetTableAlias(tbsfrom[a].Table.Type, tbUnion[tbsfrom[a].Table.Type], tbsfrom[a].Alias, _aliasRule); var alias = LocalGetTableAlias(tbsfrom[a].Table.Type, tbUnion[tbsfrom[a].Table.Type], tbsfrom[a].Alias, _aliasRule);

View File

@ -475,7 +475,22 @@ use [" + database + "];", tboldname ?? tbname);
{ {
cmd.CommandText = sql; cmd.CommandText = sql;
cmd.CommandType = CommandType.Text; cmd.CommandType = CommandType.Text;
return cmd.ExecuteScalar(); var before = new Aop.CommandBeforeEventArgs(cmd);
this._orm?.Aop.CommandBeforeHandler?.Invoke(this._orm, before);
Exception afterException = null;
try
{
return cmd.ExecuteScalar();
}
catch (Exception ex)
{
afterException = ex;
throw;
}
finally
{
this._orm?.Aop.CommandAfterHandler?.Invoke(this._orm, new Aop.CommandAfterEventArgs(before, afterException, null));
}
} }
} }
finally finally

View File

@ -39,14 +39,18 @@ namespace FreeSql.Oracle.Curd
WriteSourceSelectUnionAll(data, sb, dbParams); WriteSourceSelectUnionAll(data, sb, dbParams);
sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n");
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
if (_doNothing == false && cols.Any()) if (_doNothing == false && cols.Any())
sb.Append("WHEN MATCHED THEN \r\n") sb.Append("WHEN MATCHED THEN \r\n")
.Append(" update set ").Append(string.Join(", ", cols.Select(a => .Append(" update set ").Append(string.Join(", ", cols.Select(a =>
a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? {
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : if (_updateSetDict.TryGetValue(a.Attribute.Name, out var valsql))
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}" return $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = {valsql}";
))).Append(" \r\n"); return a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ?
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" :
$"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}";
}))).Append(" \r\n");
cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true);
if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false); if (tempPrimaryIsIdentity == false) cols = cols.Where(a => a.Attribute.IsIdentity == false || string.IsNullOrEmpty(a.DbInsertValue) == false);

View File

@ -32,11 +32,15 @@ namespace FreeSql.Oracle.Curd
sbunion.Append(_select); sbunion.Append(_select);
if (_distinct) sbunion.Append("DISTINCT "); if (_distinct) sbunion.Append("DISTINCT ");
sbunion.Append(field);
if (string.IsNullOrEmpty(_orderby) && _skip > 0) sbunion.Append(", ROWNUM AS \"__rownum__\"");
sbunion.Append(" \r\nFROM ");
var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray();
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
var isRownum = string.IsNullOrEmpty(_orderby) && _skip > 0;
if (isRownum && field == "*") sbunion.Append(tbsfrom[0].Alias).Append("."); //#1519 bug
sbunion.Append(field);
if (isRownum) sbunion.Append(", ROWNUM AS \"__rownum__\"");
sbunion.Append(" \r\nFROM ");
for (var a = 0; a < tbsfrom.Length; a++) for (var a = 0; a < tbsfrom.Length; a++)
{ {
sbunion.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); sbunion.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias);

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -500,6 +500,12 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam
else if (sqlType.StartsWith("NCLOB")) else if (sqlType.StartsWith("NCLOB"))
{ {
} }
else if (sqlType.StartsWith("RAW"))
{
}
else if (sqlType.StartsWith("LONG RAW"))
{
}
else if (char_used.ToLower() == "c") else if (char_used.ToLower() == "c")
sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)"; sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)";
else if (char_used.ToLower() == "b") else if (char_used.ToLower() == "b")

View File

@ -106,7 +106,7 @@ namespace FreeSql.Oracle
return OleDbType.VarBinary; return OleDbType.VarBinary;
case "long raw": case "long raw":
_dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]);
return OleDbType.VarBinary; return OleDbType.LongVarBinary;
case "binary_float": case "binary_float":
_dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(63)"]); _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(63)"]);
return OleDbType.Single; return OleDbType.Single;

View File

@ -46,7 +46,7 @@ public static partial class FreeSqlOracleGlobalExtensions
var _table = upsert._table; var _table = upsert._table;
var _commonUtils = upsert._commonUtils; var _commonUtils = upsert._commonUtils;
var updateTableName = upsert._tableRule?.Invoke(_table.DbName) ?? _table.DbName; var updateTableName = upsert._tableRule?.Invoke(_table.DbName) ?? _table.DbName;
var tempTableName = $"Temp_{Guid.NewGuid().ToString("N").ToUpper().Substring(0, 24)}"; var tempTableName = $"TEMP_{Guid.NewGuid().ToString("N").ToUpper().Substring(0, 24)}";
if (upsert._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower(); if (upsert._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower();
if (upsert._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper(); if (upsert._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper();
if (upsert._connection == null && upsert._orm.Ado.TransactionCurrentThread != null) if (upsert._connection == null && upsert._orm.Ado.TransactionCurrentThread != null)
@ -94,7 +94,7 @@ public static partial class FreeSqlOracleGlobalExtensions
var _table = update._table; var _table = update._table;
var _commonUtils = update._commonUtils; var _commonUtils = update._commonUtils;
var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName; var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName;
var tempTableName = $"Temp_{Guid.NewGuid().ToString("N").ToUpper().Substring(0, 24)}"; var tempTableName = $"TEMP_{Guid.NewGuid().ToString("N").ToUpper().Substring(0, 24)}";
if (update._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower(); if (update._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower();
if (update._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper(); if (update._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper();
if (update._connection == null && update._orm.Ado.TransactionCurrentThread != null) if (update._connection == null && update._orm.Ado.TransactionCurrentThread != null)

View File

@ -6,6 +6,8 @@ using System.Text.RegularExpressions;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Threading; using System.Threading;
using System.IO; using System.IO;
using System.Collections.Generic;
using System.Reflection;
namespace FreeSql.Oracle namespace FreeSql.Oracle
{ {
@ -30,13 +32,14 @@ namespace FreeSql.Oracle
this.CodeFirst = new OracleCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); this.CodeFirst = new OracleCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
#if oledb #if oledb
Select0Provider._dicMethodDataReaderGetValue[typeof(Guid)] = typeof(DbDataReader).GetMethod("GetGuid", new Type[] { typeof(int) }); Select0Provider._dicMethodDataReaderGetValueOverride[DataType.Oracle] = new Dictionary<Type, MethodInfo>();
Select0Provider._dicMethodDataReaderGetValue[typeof(bool)] = typeof(DbDataReader).GetMethod("GetBoolean", new Type[] { typeof(int) }); Select0Provider._dicMethodDataReaderGetValueOverride[DataType.Oracle][typeof(Guid)] = typeof(DbDataReader).GetMethod("GetGuid", new Type[] { typeof(int) });
Select0Provider._dicMethodDataReaderGetValue[typeof(int)] = typeof(DbDataReader).GetMethod("GetDecimal", new Type[] { typeof(int) }); Select0Provider._dicMethodDataReaderGetValueOverride[DataType.Oracle][typeof(bool)] = typeof(DbDataReader).GetMethod("GetBoolean", new Type[] { typeof(int) });
Select0Provider._dicMethodDataReaderGetValue[typeof(long)] = typeof(DbDataReader).GetMethod("GetDecimal", new Type[] { typeof(int) }); Select0Provider._dicMethodDataReaderGetValueOverride[DataType.Oracle][typeof(int)] = typeof(DbDataReader).GetMethod("GetDecimal", new Type[] { typeof(int) });
Select0Provider._dicMethodDataReaderGetValue[typeof(decimal)] = typeof(DbDataReader).GetMethod("GetDecimal", new Type[] { typeof(int) }); Select0Provider._dicMethodDataReaderGetValueOverride[DataType.Oracle][typeof(long)] = typeof(DbDataReader).GetMethod("GetDecimal", new Type[] { typeof(int) });
Select0Provider._dicMethodDataReaderGetValue[typeof(DateTime)] = typeof(DbDataReader).GetMethod("GetDateTime", new Type[] { typeof(int) }); Select0Provider._dicMethodDataReaderGetValueOverride[DataType.Oracle][typeof(decimal)] = typeof(DbDataReader).GetMethod("GetDecimal", new Type[] { typeof(int) });
Select0Provider._dicMethodDataReaderGetValue[typeof(string)] = typeof(DbDataReader).GetMethod("GetString", new Type[] { typeof(int) }); Select0Provider._dicMethodDataReaderGetValueOverride[DataType.Oracle][typeof(DateTime)] = typeof(DbDataReader).GetMethod("GetDateTime", new Type[] { typeof(int) });
Select0Provider._dicMethodDataReaderGetValueOverride[DataType.Oracle][typeof(string)] = typeof(DbDataReader).GetMethod("GetString", new Type[] { typeof(int) });
this.Aop.CommandBefore += (_, e) => this.Aop.CommandBefore += (_, e) =>
{ {

View File

@ -51,6 +51,10 @@ namespace FreeSql.Oracle
case OracleDbType.Blob: case OracleDbType.Blob:
ret = new OracleParameter { ParameterName = QuoteParamterName(parameterName), OracleDbType = dbtype2, Value = value }; ret = new OracleParameter { ParameterName = QuoteParamterName(parameterName), OracleDbType = dbtype2, Value = value };
break; break;
case OracleDbType.Raw:
case OracleDbType.LongRaw:
ret = new OracleParameter { ParameterName = QuoteParamterName(parameterName), OracleDbType = dbtype2, Value = value };
break;
} }
} }
_params?.Add(ret); _params?.Add(ret);

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -55,6 +55,10 @@ namespace FreeSql.Oracle
if (col.DbPrecision != 0) ret.Precision = col.DbPrecision; if (col.DbPrecision != 0) ret.Precision = col.DbPrecision;
if (col.DbScale != 0) ret.Scale = col.DbScale; if (col.DbScale != 0) ret.Scale = col.DbScale;
break; break;
case OleDbType.VarBinary:
case OleDbType.LongVarBinary:
ret = new OleDbParameter { ParameterName = QuoteParamterName(parameterName), OleDbType = dbtype2, Value = value };
break;
} }
} }
_params?.Add(ret); _params?.Add(ret);

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
namespace FreeSql.PostgreSQL.Curd namespace FreeSql.PostgreSQL.Curd
{ {
@ -57,11 +58,29 @@ namespace FreeSql.PostgreSQL.Curd
{ {
var ocdu = new OnConflictDoUpdate<T1>(insert.InsertIdentity()); var ocdu = new OnConflictDoUpdate<T1>(insert.InsertIdentity());
ocdu._tempPrimarys = _tempPrimarys; ocdu._tempPrimarys = _tempPrimarys;
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray());
if (_doNothing == true || cols.Any() == false) if (_doNothing == true || cols.Any() == false)
ocdu.DoNothing(); ocdu.DoNothing();
sql = ocdu.ToSql(); sql = ocdu.ToSql();
if (_updateSetDict.Any())
{
var findregex = new Regex("(t1|t2)." + _commonUtils.QuoteSqlName("test").Replace("test", "(\\w+)"));
var tableName = _commonUtils.QuoteSqlName(TableRuleInvoke());
foreach (var usd in _updateSetDict)
{
var field = _commonUtils.QuoteSqlName(usd.Key);
var findsql = $"{field} = EXCLUDED.{field}";
var usdval = findregex.Replace(usd.Value, m =>
{
if (m.Groups[1].Value == "t1") return $"{tableName}.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
return $"EXCLUDED.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
});
sql = sql.Replace(findsql, $"{field} = {usdval}");
}
}
} }
if (string.IsNullOrEmpty(sql)) return null; if (string.IsNullOrEmpty(sql)) return null;
if (insert._params?.Any() == true) dbParams.AddRange(insert._params); if (insert._params?.Any() == true) dbParams.AddRange(insert._params);

View File

@ -18,7 +18,7 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<Version>3.2.694-preview20230331</Version> <Version>3.2.697</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -56,7 +56,7 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions
var _table = upsert._table; var _table = upsert._table;
var _commonUtils = upsert._commonUtils; var _commonUtils = upsert._commonUtils;
var updateTableName = upsert._tableRule?.Invoke(_table.DbName) ?? _table.DbName; var updateTableName = upsert._tableRule?.Invoke(_table.DbName) ?? _table.DbName;
var tempTableName = $"Temp_{Guid.NewGuid().ToString("N")}"; var tempTableName = $"temp_{Guid.NewGuid().ToString("N")}";
if (upsert._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower(); if (upsert._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower();
if (upsert._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper(); if (upsert._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper();
if (upsert._connection == null && upsert._orm.Ado.TransactionCurrentThread != null) if (upsert._connection == null && upsert._orm.Ado.TransactionCurrentThread != null)
@ -107,7 +107,7 @@ public static partial class FreeSqlPostgreSQLGlobalExtensions
var _table = update._table; var _table = update._table;
var _commonUtils = update._commonUtils; var _commonUtils = update._commonUtils;
var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName; var updateTableName = update._tableRule?.Invoke(_table.DbName) ?? _table.DbName;
var tempTableName = $"Temp_{Guid.NewGuid().ToString("N")}"; var tempTableName = $"temp_{Guid.NewGuid().ToString("N")}";
if (update._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower(); if (update._orm.CodeFirst.IsSyncStructureToLower) tempTableName = tempTableName.ToLower();
if (update._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper(); if (update._orm.CodeFirst.IsSyncStructureToUpper) tempTableName = tempTableName.ToUpper();
if (update._connection == null && update._orm.Ado.TransactionCurrentThread != null) if (update._connection == null && update._orm.Ado.TransactionCurrentThread != null)

View File

@ -21,91 +21,95 @@ namespace FreeSql.PostgreSQL
public class PostgreSQLProvider<TMark> : BaseDbProvider, IFreeSql<TMark> public class PostgreSQLProvider<TMark> : BaseDbProvider, IFreeSql<TMark>
{ {
static PostgreSQLProvider() static int _firstInit = 1;
static void InitInternal()
{ {
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(BigInteger)] = true; if (Interlocked.Exchange(ref _firstInit, 0) == 1) //不能放在 static ctor .NetFramework 可能报初始化类型错误
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(BitArray)] = true; {
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlPoint)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(BigInteger)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlLine)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(BitArray)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlLSeg)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlPoint)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlBox)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlLine)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlPath)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlLSeg)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlPolygon)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlBox)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlCircle)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlPath)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof((IPAddress Address, int Subnet))] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlPolygon)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(IPAddress)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlCircle)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PhysicalAddress)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof((IPAddress Address, int Subnet))] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange<int>)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(IPAddress)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange<long>)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PhysicalAddress)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange<decimal>)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange<int>)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange<DateTime>)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange<long>)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange<decimal>)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NpgsqlRange<DateTime>)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisPoint)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisPoint)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisLineString)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisLineString)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisPolygon)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisPolygon)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisMultiPoint)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisMultiPoint)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisMultiLineString)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisMultiLineString)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisMultiPolygon)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisMultiPolygon)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisGeometry)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisGeometry)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisGeometryCollection)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(PostgisGeometryCollection)] = true;
#if nts #if nts
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.Point)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.Point)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.LineString)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.LineString)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.Polygon)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.Polygon)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.MultiPoint)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.MultiPoint)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.MultiLineString)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.MultiLineString)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.MultiPolygon)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.MultiPolygon)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.Geometry)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.Geometry)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.GeometryCollection)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(NetTopologySuite.Geometries.GeometryCollection)] = true;
#endif #endif
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(Dictionary<string, string>)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(Dictionary<string, string>)] = true;
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JToken)] = true; Utils.dicExecuteArrayRowReadClassOrTuple[typeof(JToken)] = true;
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 MethodJTokenFromObject = typeof(JToken).GetMethod("FromObject", new[] { typeof(object) });
var MethodJObjectFromObject = typeof(JObject).GetMethod("FromObject", new[] { typeof(object) }); var MethodJObjectFromObject = typeof(JObject).GetMethod("FromObject", new[] { typeof(object) });
var MethodJArrayFromObject = typeof(JArray).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) }); var MethodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) });
var MethodToString = typeof(Utils).GetMethod("ToStringConcat", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(object) }, null); var MethodToString = typeof(Utils).GetMethod("ToStringConcat", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(object) }, null);
Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) => Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) =>
{
switch (type.FullName)
{ {
case "Newtonsoft.Json.Linq.JToken": switch (type.FullName)
{
case "Newtonsoft.Json.Linq.JToken":
return Expression.IfThenElse(
Expression.TypeIs(valueExp, typeof(string)),
Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJTokenParse, Expression.Convert(valueExp, typeof(string))), typeof(JToken))),
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.IfThenElse( return Expression.IfThenElse(
Expression.TypeIs(valueExp, typeof(string)), Expression.TypeIs(valueExp, typeof(string)),
Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJTokenParse, Expression.Convert(valueExp, typeof(string))), typeof(JToken))), Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJsonConvertDeserializeObject, Expression.Convert(valueExp, typeof(string)), Expression.Constant(type, typeof(Type))), type)),
Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJTokenFromObject, valueExp), typeof(JToken)))); Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJsonConvertDeserializeObject, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(string)), Expression.Constant(type, typeof(Type))), type)));
case "Newtonsoft.Json.Linq.JObject": return null;
return Expression.IfThenElse( });
Expression.TypeIs(valueExp, typeof(string)),
Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectParse, Expression.Convert(valueExp, typeof(string))), typeof(JObject))), Select0Provider._dicMethodDataReaderGetValue[typeof(Guid)] = typeof(DbDataReader).GetMethod("GetGuid", new Type[] { typeof(int) });
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.IfThenElse(
Expression.TypeIs(valueExp, typeof(string)),
Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJsonConvertDeserializeObject, Expression.Convert(valueExp, typeof(string)), Expression.Constant(type, typeof(Type))), type)),
Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJsonConvertDeserializeObject, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(string)), Expression.Constant(type, typeof(Type))), type)));
return null;
});
Select0Provider._dicMethodDataReaderGetValue[typeof(Guid)] = typeof(DbDataReader).GetMethod("GetGuid", new Type[] { typeof(int) });
} }
public override ISelect<T1> CreateSelectProvider<T1>(object dywhere) => new PostgreSQLSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public override ISelect<T1> CreateSelectProvider<T1>(object dywhere) => new PostgreSQLSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
@ -116,6 +120,7 @@ namespace FreeSql.PostgreSQL
public PostgreSQLProvider(string masterConnectionString, string[] slaveConnectionString, Func<DbConnection> connectionFactory = null) public PostgreSQLProvider(string masterConnectionString, string[] slaveConnectionString, Func<DbConnection> connectionFactory = null)
{ {
InitInternal();
this.InternalCommonUtils = new PostgreSQLUtils(this); this.InternalCommonUtils = new PostgreSQLUtils(this);
this.InternalCommonExpression = new PostgreSQLExpression(this.InternalCommonUtils); this.InternalCommonExpression = new PostgreSQLExpression(this.InternalCommonUtils);

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
namespace FreeSql.QuestDb.Curd namespace FreeSql.QuestDb.Curd
{ {
@ -57,11 +58,29 @@ namespace FreeSql.QuestDb.Curd
{ {
var ocdu = new OnConflictDoUpdate<T1>(insert.InsertIdentity()); var ocdu = new OnConflictDoUpdate<T1>(insert.InsertIdentity());
ocdu._tempPrimarys = _tempPrimarys; ocdu._tempPrimarys = _tempPrimarys;
var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false); var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray());
if (_doNothing == true || cols.Any() == false) if (_doNothing == true || cols.Any() == false)
ocdu.DoNothing(); ocdu.DoNothing();
sql = ocdu.ToSql(); sql = ocdu.ToSql();
if (_updateSetDict.Any())
{
var findregex = new Regex("(t1|t2)." + _commonUtils.QuoteSqlName("test").Replace("test", "(\\w+)"));
var tableName = _commonUtils.QuoteSqlName(TableRuleInvoke());
foreach (var usd in _updateSetDict)
{
var field = _commonUtils.QuoteSqlName(usd.Key);
var findsql = $"{field} = EXCLUDED.{field}";
var usdval = findregex.Replace(usd.Value, m =>
{
if (m.Groups[1].Value == "t1") return $"{tableName}.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
return $"EXCLUDED.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
});
sql = sql.Replace(findsql, $"{field} = {usdval}");
}
}
} }
if (string.IsNullOrEmpty(sql)) return null; if (string.IsNullOrEmpty(sql)) return null;
if (insert._params?.Any() == true) dbParams.AddRange(insert._params); if (insert._params?.Any() == true) dbParams.AddRange(insert._params);

Some files were not shown because too many files have changed in this diff Show More